Merge branch 'V2MultiWear' of git://github.com/Shyotl/SingularityViewer into V2MultiWear
Conflicts: indra/newview/llfloateravatarlist.cpp indra/newview/llfloatermessagelog.cpp indra/newview/llstartup.cpp indra/newview/llviewermenu.cpp indra/newview/llviewermessage.cpp indra/newview/skins/default/xui/fr/menu_inventory.xml
This commit is contained in:
@@ -37,6 +37,7 @@ include(LLUI)
|
||||
include(LLVFS)
|
||||
include(LLWindow)
|
||||
include(LLXML)
|
||||
include(LLXUIXML)
|
||||
include(LScript)
|
||||
include(Linking)
|
||||
include(NDOF)
|
||||
@@ -71,6 +72,7 @@ include_directories(
|
||||
${LLVFS_INCLUDE_DIRS}
|
||||
${LLWINDOW_INCLUDE_DIRS}
|
||||
${LLXML_INCLUDE_DIRS}
|
||||
${LLXUIXML_INCLUDE_DIRS}
|
||||
${LSCRIPT_INCLUDE_DIRS}
|
||||
${LSCRIPT_INCLUDE_DIRS}/lscript_compile
|
||||
)
|
||||
@@ -86,7 +88,6 @@ set(viewer_SOURCE_FILES
|
||||
lggdicdownload.cpp
|
||||
floaterao.cpp
|
||||
floatervoicelicense.cpp
|
||||
cofmgr.cpp
|
||||
lldaycyclemanager.cpp
|
||||
llenvmanager.cpp
|
||||
llwlhandlers.cpp
|
||||
@@ -122,7 +123,9 @@ set(viewer_SOURCE_FILES
|
||||
llagentpilot.cpp
|
||||
llagentui.cpp
|
||||
llagentwearables.cpp
|
||||
llagentwearablesfetch.cpp
|
||||
llanimstatelabels.cpp
|
||||
llappearancemgr.cpp
|
||||
llappviewer.cpp
|
||||
llassetconverter.cpp
|
||||
llassetuploadresponders.cpp
|
||||
@@ -308,6 +311,7 @@ set(viewer_SOURCE_FILES
|
||||
llinventorypanel.cpp
|
||||
lljoystickbutton.cpp
|
||||
lllandmarklist.cpp
|
||||
lllocaltextureobject.cpp
|
||||
lllocalinventory.cpp
|
||||
lllogchat.cpp
|
||||
llloginhandler.cpp
|
||||
@@ -329,6 +333,7 @@ set(viewer_SOURCE_FILES
|
||||
llnamelistctrl.cpp
|
||||
llnetmap.cpp
|
||||
llnotify.cpp
|
||||
lloutfitobserver.cpp
|
||||
lloverlaybar.cpp
|
||||
llpanelaudioprefs.cpp
|
||||
llpanelaudiovolume.cpp
|
||||
@@ -357,7 +362,7 @@ set(viewer_SOURCE_FILES
|
||||
llpanelgrouproles.cpp
|
||||
llpanelgroupvoting.cpp
|
||||
llpanelinput.cpp
|
||||
llpanelinventory.cpp
|
||||
llpanelobjectinventory.cpp
|
||||
llpanelland.cpp
|
||||
llpanellandaudio.cpp
|
||||
llpanellandmedia.cpp
|
||||
@@ -411,7 +416,9 @@ set(viewer_SOURCE_FILES
|
||||
llstylemap.cpp
|
||||
llsurface.cpp
|
||||
llsurfacepatch.cpp
|
||||
lltexglobalcolor.cpp
|
||||
lltexlayer.cpp
|
||||
lltexlayerparams.cpp
|
||||
lltexturecache.cpp
|
||||
lltexturectrl.cpp
|
||||
lltexturefetch.cpp
|
||||
@@ -571,7 +578,6 @@ set(viewer_HEADER_FILES
|
||||
aoremotectrl.h
|
||||
floaterao.h
|
||||
floatervoicelicense.h
|
||||
cofmgr.h
|
||||
lldaycyclemanager.h
|
||||
llenvmanager.h
|
||||
llwlhandlers.h
|
||||
@@ -607,8 +613,10 @@ set(viewer_HEADER_FILES
|
||||
llagentpilot.h
|
||||
llagentui.h
|
||||
llagentwearables.h
|
||||
llagentwearablesfetch.h
|
||||
llanimstatelabels.h
|
||||
llappearance.h
|
||||
llappearancemgr.h
|
||||
llappviewer.h
|
||||
llassetconverter.h
|
||||
llassetuploadresponders.h
|
||||
@@ -794,6 +802,7 @@ set(viewer_HEADER_FILES
|
||||
lljoystickbutton.h
|
||||
lllandmarklist.h
|
||||
lllightconstants.h
|
||||
lllocaltextureobject.h
|
||||
lllocalinventory.h
|
||||
lllogchat.h
|
||||
llloginhandler.h
|
||||
@@ -815,6 +824,7 @@ set(viewer_HEADER_FILES
|
||||
llnamelistctrl.h
|
||||
llnetmap.h
|
||||
llnotify.h
|
||||
lloutfitobserver.h
|
||||
lloverlaybar.h
|
||||
llpanelaudioprefs.h
|
||||
llpanelaudiovolume.h
|
||||
@@ -843,7 +853,7 @@ set(viewer_HEADER_FILES
|
||||
llpanelgrouproles.h
|
||||
llpanelgroupvoting.h
|
||||
llpanelinput.h
|
||||
llpanelinventory.h
|
||||
llpanelobjectinventory.h
|
||||
llpanelland.h
|
||||
llpanellandaudio.h
|
||||
llpanellandmedia.h
|
||||
@@ -900,7 +910,9 @@ set(viewer_HEADER_FILES
|
||||
llsurface.h
|
||||
llsurfacepatch.h
|
||||
lltable.h
|
||||
lltexglobalcolor.h
|
||||
lltexlayer.h
|
||||
lltexlayerparams.h
|
||||
lltexturecache.h
|
||||
lltexturectrl.h
|
||||
lltexturefetch.h
|
||||
@@ -1522,6 +1534,7 @@ target_link_libraries(${VIEWER_BINARY_NAME}
|
||||
${LLVFS_LIBRARIES}
|
||||
${LLWINDOW_LIBRARIES}
|
||||
${LLXML_LIBRARIES}
|
||||
${LLXUIXML_LIBRARIES}
|
||||
${LSCRIPT_LIBRARIES}
|
||||
${LLMATH_LIBRARIES}
|
||||
${LLCOMMON_LIBRARIES}
|
||||
|
||||
@@ -2076,6 +2076,28 @@
|
||||
<key>Value</key>
|
||||
<integer>2</integer>
|
||||
</map>
|
||||
<key>AvatarBakedTextureUploadTimeout</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Specifes the maximum time in seconds to wait before sending your baked textures for avatar appearance. Set to 0 to disable and wait until all baked textures are at highest resolution.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>60</integer>
|
||||
</map>
|
||||
<key>AvatarBakedLocalTextureUpdateTimeout</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Specifes the maximum time in seconds to wait before updating your appearance during appearance mode.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>10</integer>
|
||||
</map>
|
||||
<key>AvatarPhysics</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -3994,8 +4016,30 @@
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string/>
|
||||
<string />
|
||||
</map>
|
||||
<key>DebugAvatarRezTime</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Display times for avatars to resolve.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>DebugAvatarLocalTexLoadedTime</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Display time for loading avatar local textures.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>DebugBeaconLineWidth</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -6709,6 +6753,17 @@
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>ForceAssetFail</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Force wearable fetches to fail for this asset type.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>U32</string>
|
||||
<key>Value</key>
|
||||
<integer>255</integer>
|
||||
</map>
|
||||
<key>ForceShowGrid</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -7949,6 +8004,17 @@
|
||||
<key>Value</key>
|
||||
<real>128.0</real>
|
||||
</map>
|
||||
<key>MaxWearableWaitTime</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Max seconds to wait for wearable assets to fetch.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>F32</string>
|
||||
<key>Value</key>
|
||||
<real>60.0</real>
|
||||
</map>
|
||||
<key>MeanCollisionBump</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -8409,8 +8475,19 @@
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>MyOutfitsAutofill</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Always autofill My Outfits from library when empty (else happens just once).</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>0</integer>
|
||||
</map>
|
||||
<key>NearMeRange</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
@@ -14694,6 +14771,17 @@
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
<key>OutfitOperationsTimeout</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Timeout for outfit related operations.</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>S32</string>
|
||||
<key>Value</key>
|
||||
<integer>180</integer>
|
||||
</map>
|
||||
<key>UseHTTPInventory</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
@@ -98,13 +98,11 @@ void LLPrefsAscentVan::onCommitClientTag(LLUICtrl* ctrl, void* userdata)
|
||||
gSavedSettings.setString("AscentReportClientUUID", client_uuid);
|
||||
gSavedSettings.setU32("AscentReportClientIndex", client_index);
|
||||
|
||||
LLVOAvatar* avatar = gAgentAvatarp;
|
||||
|
||||
if (avatar)
|
||||
if (gAgentAvatarp)
|
||||
{
|
||||
// Slam pending upload count to "unstick" things
|
||||
bool slam_for_debug = true;
|
||||
avatar->forceBakeAllTextures(slam_for_debug);
|
||||
gAgentAvatarp->forceBakeAllTextures(slam_for_debug);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6387,8 +6387,6 @@
|
||||
<layer
|
||||
name="facialhair"
|
||||
global_color="hair_color">
|
||||
<morph_mask
|
||||
morph_name="Displace_Hair_Facial" />
|
||||
|
||||
<texture
|
||||
tga_file="head_hair.tga"
|
||||
@@ -7294,12 +7292,6 @@
|
||||
<texture
|
||||
local_texture="upper_shirt" />
|
||||
|
||||
<morph_mask
|
||||
morph_name="Displace_Loose_Upperbody" />
|
||||
|
||||
<morph_mask
|
||||
morph_name="Shirtsleeve_flair" />
|
||||
|
||||
<param
|
||||
id="803"
|
||||
group="0"
|
||||
@@ -8360,18 +8352,6 @@
|
||||
<texture
|
||||
local_texture="lower_pants" />
|
||||
|
||||
<morph_mask
|
||||
morph_name="Displace_Loose_Lowerbody" />
|
||||
|
||||
<morph_mask
|
||||
morph_name="Leg_Pantflair" />
|
||||
|
||||
<morph_mask
|
||||
morph_name="Low_Crotch" />
|
||||
|
||||
<morph_mask
|
||||
morph_name="Leg_Longcuffs" />
|
||||
|
||||
<param
|
||||
id="806"
|
||||
group="0"
|
||||
@@ -11863,6 +11843,37 @@
|
||||
value_max="1">
|
||||
<param_driver />
|
||||
</param>
|
||||
</driver_parameters>
|
||||
</driver_parameters>
|
||||
|
||||
<morph_masks>
|
||||
<mask
|
||||
morph_name="Displace_Hair_Facial"
|
||||
body_region="head"
|
||||
layer="facialhair" />
|
||||
<mask
|
||||
morph_name="Displace_Loose_Upperbody"
|
||||
body_region="upper_body"
|
||||
layer="upper_clothes" />
|
||||
<mask
|
||||
morph_name="Shirtsleeve_flair"
|
||||
body_region="upper_body"
|
||||
layer="upper_clothes" />
|
||||
<mask
|
||||
morph_name="Displace_Loose_Lowerbody"
|
||||
body_region="lower_body"
|
||||
layer="lower_pants" />
|
||||
<mask
|
||||
morph_name="Leg_Pantflair"
|
||||
body_region="lower_body"
|
||||
layer="lower_pants" />
|
||||
<mask
|
||||
morph_name="Low_Crotch"
|
||||
body_region="lower_body"
|
||||
layer="lower_pants" />
|
||||
<mask
|
||||
morph_name="Leg_Longcuffs"
|
||||
body_region="lower_body"
|
||||
layer="lower_pants" />
|
||||
</morph_masks>
|
||||
</linden_avatar>
|
||||
|
||||
|
||||
@@ -1,536 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (c) 2010, Kitty Barnett
|
||||
*
|
||||
* The source code in this file is provided to you under the terms of the
|
||||
* GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
|
||||
* in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge that
|
||||
* you have read and understood your obligations described above, and agree to
|
||||
* abide by those obligations.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "cofmgr.h"
|
||||
#include "llagent.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llcommonutils.h"
|
||||
#include "llerror.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "rlvviewer2.h"
|
||||
|
||||
// ============================================================================
|
||||
// Inventory helper classes
|
||||
//
|
||||
|
||||
class LLCOFLinkTargetFetcher : public LLInventoryFetchItemsObserver
|
||||
{
|
||||
public:
|
||||
LLCOFLinkTargetFetcher(const uuid_vec_t& idItems) : LLInventoryFetchItemsObserver(idItems) {}
|
||||
/*virtual*/ ~LLCOFLinkTargetFetcher() {}
|
||||
|
||||
/*virtual*/ void done()
|
||||
{
|
||||
// We shouldn't be messing with inventory items during LLInventoryModel::notifyObservers()
|
||||
doOnIdleOneTime(boost::bind(&LLCOFLinkTargetFetcher::doneIdle, this));
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
|
||||
void doneIdle()
|
||||
{
|
||||
LLCOFMgr::instance().checkCOF();
|
||||
LLCOFMgr::instance().setLinkAttachments(true);
|
||||
LLCOFMgr::instance().updateAttachments();
|
||||
LLCOFMgr::instance().synchWearables();
|
||||
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
class LLCOFFetcher : public LLInventoryFetchDescendentsObserver
|
||||
{
|
||||
public:
|
||||
LLCOFFetcher(const LLUUID& cat_id) : LLInventoryFetchDescendentsObserver(cat_id) {}
|
||||
/*virtual*/ ~LLCOFFetcher() {}
|
||||
|
||||
/*virtual*/ void done()
|
||||
{
|
||||
// We shouldn't be messing with inventory items during LLInventoryModel::notifyObservers()
|
||||
doOnIdleOneTime(boost::bind(&LLCOFFetcher::doneIdle, this));
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
|
||||
void doneIdle()
|
||||
{
|
||||
uuid_vec_t idItems;
|
||||
|
||||
// Add the link targets for COF
|
||||
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
|
||||
gInventory.collectDescendents(LLCOFMgr::getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH);
|
||||
for (S32 idxItem = 0; idxItem < items.count(); idxItem++)
|
||||
{
|
||||
const LLViewerInventoryItem* pItem = items.get(idxItem);
|
||||
if (!pItem)
|
||||
continue;
|
||||
idItems.push_back(pItem->getLinkedUUID());
|
||||
}
|
||||
|
||||
// Add all currently worn wearables
|
||||
for (S32 idxType = 0; idxType < LLWearableType::WT_COUNT; idxType++)
|
||||
{
|
||||
const LLUUID& idItem = gAgentWearables.getWearableItemID((LLWearableType::EType)idxType,0); // TODO: MULTI-WEARABLE
|
||||
if (idItem.isNull())
|
||||
continue;
|
||||
idItems.push_back(idItem);
|
||||
}
|
||||
|
||||
// Add all currently worn attachments
|
||||
const LLVOAvatar* pAvatar = gAgentAvatarp;
|
||||
if (pAvatar)
|
||||
{
|
||||
for (LLVOAvatar::attachment_map_t::const_iterator itAttachPt = pAvatar->mAttachmentPoints.begin();
|
||||
itAttachPt != pAvatar->mAttachmentPoints.end(); ++itAttachPt)
|
||||
{
|
||||
const LLViewerJointAttachment* pAttachPt = itAttachPt->second;
|
||||
for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator itAttachment = pAttachPt->mAttachedObjects.begin();
|
||||
itAttachment != pAttachPt->mAttachedObjects.end(); ++itAttachment)
|
||||
{
|
||||
const LLUUID& idItem = (*itAttachment)->getAttachmentItemID();
|
||||
if (idItem.isNull())
|
||||
continue;
|
||||
idItems.push_back(idItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fetch it all
|
||||
LLCOFLinkTargetFetcher* pFetcher = new LLCOFLinkTargetFetcher(idItems);
|
||||
pFetcher->startFetch();
|
||||
if (pFetcher->isFinished())
|
||||
{
|
||||
pFetcher->done();
|
||||
}
|
||||
else
|
||||
{
|
||||
gInventory.addObserver(pFetcher);
|
||||
|
||||
// It doesn't look like we *really* need the link targets so we can do a preliminary initialization now already
|
||||
LLCOFMgr::instance().setLinkAttachments(true);
|
||||
LLCOFMgr::instance().updateAttachments();
|
||||
}
|
||||
|
||||
delete this;
|
||||
}
|
||||
};
|
||||
|
||||
class LLDeferredAddLinkTargetFetcher : public LLInventoryFetchItemsObserver
|
||||
{
|
||||
public:
|
||||
LLDeferredAddLinkTargetFetcher(const LLUUID& idItem, LLPointer<LLInventoryCallback> cb)
|
||||
: LLInventoryFetchItemsObserver(idItem), m_Callback(cb)
|
||||
{}
|
||||
LLDeferredAddLinkTargetFetcher(const uuid_vec_t& idItems, LLPointer<LLInventoryCallback> cb)
|
||||
: LLInventoryFetchItemsObserver(idItems), m_Callback(cb)
|
||||
{}
|
||||
/*virtual*/ ~LLDeferredAddLinkTargetFetcher() {}
|
||||
|
||||
/*virtual*/ void done()
|
||||
{
|
||||
// We shouldn't be messing with inventory items during LLInventoryModel::notifyObservers()
|
||||
doOnIdleOneTime(boost::bind(&LLDeferredAddLinkTargetFetcher::doneIdle, this));
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
|
||||
void doneIdle()
|
||||
{
|
||||
for (uuid_vec_t::const_iterator itItemId = mComplete.begin(); itItemId != mComplete.end(); ++itItemId)
|
||||
{
|
||||
const LLViewerInventoryItem* pItem = gInventory.getItem(*itItemId);
|
||||
if (!pItem)
|
||||
continue;
|
||||
LLCOFMgr::instance().addCOFItemLink(pItem, m_Callback);
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
protected:
|
||||
LLPointer<LLInventoryCallback> m_Callback;
|
||||
};
|
||||
|
||||
class LLLinkAttachmentCallback : public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
LLLinkAttachmentCallback() {}
|
||||
/*virtual*/ ~LLLinkAttachmentCallback() {}
|
||||
/*virtual*/ void fire(const LLUUID& idItem) { LLCOFMgr::instance().onLinkAttachmentComplete(idItem); }
|
||||
};
|
||||
|
||||
class LLLinkWearableCallback : public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
LLLinkWearableCallback() {}
|
||||
/*virtual*/ ~LLLinkWearableCallback() {}
|
||||
/*virtual*/ void fire(const LLUUID& idItem) { LLCOFMgr::instance().onLinkWearableComplete(idItem); }
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Helper functions
|
||||
//
|
||||
|
||||
void LLCOFMgr::checkCOF()
|
||||
{
|
||||
const LLUUID idCOF = getCOF();
|
||||
const LLUUID idLAF = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
|
||||
|
||||
// Check COF for non-links and move them to Lost&Found
|
||||
LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems;
|
||||
gInventory.getDirectDescendentsOf(idCOF, pFolders, pItems);
|
||||
for (S32 idxFolder = 0, cntFolder = pFolders->count(); idxFolder < cntFolder; idxFolder++)
|
||||
{
|
||||
LLViewerInventoryCategory* pFolder = pFolders->get(idxFolder).get();
|
||||
if ( (pFolder) && (idLAF.notNull()) )
|
||||
change_category_parent(&gInventory, pFolder, idLAF, false);
|
||||
}
|
||||
for (S32 idxItem = 0, cntItem = pItems->count(); idxItem < cntItem; idxItem++)
|
||||
{
|
||||
LLViewerInventoryItem* pItem = pItems->get(idxItem).get();
|
||||
if ( (pItem) && (!pItem->getIsLinkType()) && (idLAF.notNull()) )
|
||||
change_item_parent(&gInventory, pItem, idLAF, false);
|
||||
}
|
||||
}
|
||||
|
||||
void LLCOFMgr::fetchCOF()
|
||||
{
|
||||
static bool sFetched = false;
|
||||
if (!sFetched)
|
||||
{
|
||||
const LLUUID idCOF = getCOF();
|
||||
if (idCOF.isNull())
|
||||
{
|
||||
LL_ERRS("COFMgr") << "Unable to find (or create) COF" << LL_ENDL;
|
||||
return;
|
||||
}
|
||||
|
||||
LLCOFFetcher* pFetcher = new LLCOFFetcher(idCOF);
|
||||
pFetcher->startFetch();
|
||||
if (pFetcher->isFinished())
|
||||
pFetcher->done();
|
||||
else
|
||||
gInventory.addObserver(pFetcher);
|
||||
|
||||
sFetched = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLCOFMgr::getDescendentsOfAssetType(const LLUUID& idCat, LLInventoryModel::item_array_t& items,
|
||||
LLAssetType::EType typeAsset, bool fFollowFolderLinks)
|
||||
{
|
||||
LLInventoryModel::cat_array_t folders;
|
||||
LLIsType f(typeAsset);
|
||||
gInventory.collectDescendentsIf(idCat, folders, items, LLInventoryModel::EXCLUDE_TRASH, f, fFollowFolderLinks);
|
||||
}
|
||||
|
||||
void LLCOFMgr::addCOFItemLink(const LLUUID& idItem, LLPointer<LLInventoryCallback> cb)
|
||||
{
|
||||
const LLViewerInventoryItem *pItem = gInventory.getItem(idItem);
|
||||
if (!pItem)
|
||||
{
|
||||
LLDeferredAddLinkTargetFetcher* pFetcher = new LLDeferredAddLinkTargetFetcher(idItem, cb);
|
||||
pFetcher->startFetch();
|
||||
gInventory.addObserver(pFetcher);
|
||||
return;
|
||||
}
|
||||
addCOFItemLink(pItem, cb);
|
||||
}
|
||||
|
||||
void LLCOFMgr::addCOFItemLink(const LLInventoryItem* pItem, LLPointer<LLInventoryCallback> cb)
|
||||
{
|
||||
if ( (!pItem) || (isLinkInCOF(pItem->getLinkedUUID())) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, pItem->getLinkedUUID());
|
||||
|
||||
const std::string strDescr = (pItem->getIsLinkType()) ? pItem->getDescription() : "";
|
||||
link_inventory_item(gAgent.getID(), pItem->getLinkedUUID(), getCOF(), pItem->getName(), strDescr, LLAssetType::AT_LINK, cb);
|
||||
}
|
||||
|
||||
bool LLCOFMgr::isLinkInCOF(const LLUUID& idItem) const
|
||||
{
|
||||
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
|
||||
LLLinkedItemIDMatches f(gInventory.getLinkedItemID(idItem));
|
||||
gInventory.collectDescendentsIf(getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH, f);
|
||||
return (!items.empty());
|
||||
}
|
||||
|
||||
void LLCOFMgr::removeCOFItemLinks(const LLUUID& idItem)
|
||||
{
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
|
||||
|
||||
LLInventoryModel::cat_array_t folders; LLInventoryModel::item_array_t items;
|
||||
gInventory.collectDescendents(getCOF(), folders, items, LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
for (S32 idxItem = 0; idxItem < items.count(); idxItem++)
|
||||
{
|
||||
const LLInventoryItem* pItem = items.get(idxItem).get();
|
||||
if ( (pItem->getIsLinkType()) && (idItem == pItem->getLinkedUUID()) )
|
||||
gInventory.purgeObject(pItem->getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLCOFMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const
|
||||
{
|
||||
if (!isLinkInCOF(obj_id)) return FALSE;
|
||||
|
||||
// If a non-link somehow ended up in COF, allow deletion.
|
||||
const LLInventoryObject *obj = gInventory.getObject(obj_id);
|
||||
if (obj && !obj->getIsLinkType())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// For now, don't allow direct deletion from the COF. Instead, force users
|
||||
// to choose "Detach" or "Take Off".
|
||||
return TRUE;
|
||||
/*
|
||||
const LLInventoryObject *obj = gInventory.getObject(obj_id);
|
||||
if (!obj) return FALSE;
|
||||
|
||||
// Can't delete bodyparts, since this would be equivalent to removing the item.
|
||||
if (obj->getType() == LLAssetType::AT_BODYPART) return TRUE;
|
||||
|
||||
// Can't delete the folder link, since this is saved for bookkeeping.
|
||||
if (obj->getActualType() == LLAssetType::AT_LINK_FOLDER) return TRUE;
|
||||
|
||||
return FALSE;
|
||||
*/
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Attachment functions
|
||||
//
|
||||
|
||||
void LLCOFMgr::addAttachment(const LLUUID& idItem)
|
||||
{
|
||||
if ( (isLinkInCOF(idItem)) || (std::find(m_PendingAttachLinks.begin(), m_PendingAttachLinks.end(), idItem) != m_PendingAttachLinks.end()) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
|
||||
m_PendingAttachLinks.push_back(idItem);
|
||||
|
||||
if (m_fLinkAttachments)
|
||||
{
|
||||
LLPointer<LLInventoryCallback> cb = new LLLinkAttachmentCallback();
|
||||
addCOFItemLink(idItem, cb);
|
||||
}
|
||||
}
|
||||
|
||||
void LLCOFMgr::removeAttachment(const LLUUID& idItem)
|
||||
{
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
|
||||
|
||||
// Remove the attachment from the pending list
|
||||
uuid_vec_t::iterator itPending = std::find(m_PendingAttachLinks.begin(), m_PendingAttachLinks.end(), idItem);
|
||||
if (itPending != m_PendingAttachLinks.end())
|
||||
m_PendingAttachLinks.erase(itPending);
|
||||
|
||||
if (m_fLinkAttachments)
|
||||
{
|
||||
removeCOFItemLinks(idItem);
|
||||
}
|
||||
}
|
||||
|
||||
void LLCOFMgr::setLinkAttachments(bool fEnable)
|
||||
{
|
||||
m_fLinkAttachments = fEnable;
|
||||
|
||||
if (m_fLinkAttachments)
|
||||
linkPendingAttachments();
|
||||
}
|
||||
|
||||
void LLCOFMgr::linkPendingAttachments()
|
||||
{
|
||||
LLPointer<LLInventoryCallback> cb = NULL;
|
||||
for (uuid_vec_t::const_iterator itPending = m_PendingAttachLinks.begin(); itPending != m_PendingAttachLinks.end(); ++itPending)
|
||||
{
|
||||
const LLUUID& idAttachItem = *itPending;
|
||||
if ( (gAgentAvatarp->isWearingAttachment(idAttachItem)) && (!isLinkInCOF(idAttachItem)) )
|
||||
{
|
||||
if (!cb)
|
||||
cb = new LLLinkAttachmentCallback();
|
||||
addCOFItemLink(idAttachItem, cb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLCOFMgr::onLinkAttachmentComplete(const LLUUID& idItem)
|
||||
{
|
||||
const LLUUID& idItemBase = gInventory.getLinkedItemID(idItem);
|
||||
|
||||
// Remove the attachment from the pending list
|
||||
uuid_vec_t::iterator itPending = std::find(m_PendingAttachLinks.begin(), m_PendingAttachLinks.end(), idItemBase);
|
||||
if (itPending != m_PendingAttachLinks.end())
|
||||
m_PendingAttachLinks.erase(itPending);
|
||||
|
||||
// It may have been detached already in which case we should remove the COF link
|
||||
if ( (gAgentAvatarp) && (!gAgentAvatarp->isWearingAttachment(idItemBase)) )
|
||||
removeCOFItemLinks(idItemBase);
|
||||
}
|
||||
|
||||
void LLCOFMgr::updateAttachments()
|
||||
{
|
||||
/*const*/ LLVOAvatar* pAvatar = gAgentAvatarp;
|
||||
if (!pAvatar)
|
||||
return;
|
||||
|
||||
const LLUUID idCOF = getCOF();
|
||||
|
||||
// Grab all attachment links currently in COF
|
||||
LLInventoryModel::item_array_t items;
|
||||
getDescendentsOfAssetType(idCOF, items, LLAssetType::AT_OBJECT, true);
|
||||
|
||||
// Include attachments which should be in COF but don't have their link created yet
|
||||
uuid_vec_t::iterator itPendingAttachLink = m_PendingAttachLinks.begin();
|
||||
while (itPendingAttachLink != m_PendingAttachLinks.end())
|
||||
{
|
||||
const LLUUID& idItem = *itPendingAttachLink;
|
||||
if ( (!pAvatar->isWearingAttachment(idItem)) || (isLinkInCOF(idItem)) )
|
||||
{
|
||||
itPendingAttachLink = m_PendingAttachLinks.erase(itPendingAttachLink);
|
||||
continue;
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* pItem = gInventory.getItem(idItem);
|
||||
if (pItem)
|
||||
items.push_back(pItem);
|
||||
|
||||
++itPendingAttachLink;
|
||||
}
|
||||
|
||||
// Don't remove attachments until avatar is fully loaded (should reduce random attaching/detaching/reattaching at log-on)
|
||||
LLAgentWearables::userUpdateAttachments(items, !pAvatar->isFullyLoaded());
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Wearable functions
|
||||
//
|
||||
|
||||
void LLCOFMgr::addWearable(const LLUUID& idItem)
|
||||
{
|
||||
if ( (isLinkInCOF(idItem)) || (std::find(m_PendingWearableLinks.begin(), m_PendingWearableLinks.end(), idItem) != m_PendingWearableLinks.end()) )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
|
||||
m_PendingWearableLinks.push_back(idItem);
|
||||
|
||||
LLPointer<LLInventoryCallback> cb = new LLLinkWearableCallback();
|
||||
addCOFItemLink(idItem, cb);
|
||||
}
|
||||
|
||||
void LLCOFMgr::removeWearable(const LLUUID& idItem)
|
||||
{
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, idItem);
|
||||
|
||||
// Remove the attachment from the pending list
|
||||
uuid_vec_t::iterator itPending = std::find(m_PendingWearableLinks.begin(), m_PendingWearableLinks.end(), idItem);
|
||||
if (itPending != m_PendingWearableLinks.end())
|
||||
m_PendingWearableLinks.erase(itPending);
|
||||
|
||||
removeCOFItemLinks(idItem);
|
||||
}
|
||||
|
||||
void LLCOFMgr::onLinkWearableComplete(const LLUUID& idItem)
|
||||
{
|
||||
const LLUUID& idItemBase = gInventory.getLinkedItemID(idItem);
|
||||
|
||||
// Remove the attachment from the pending list
|
||||
uuid_vec_t::iterator itPending = std::find(m_PendingWearableLinks.begin(), m_PendingWearableLinks.end(), idItemBase);
|
||||
if (itPending != m_PendingWearableLinks.end())
|
||||
m_PendingWearableLinks.erase(itPending);
|
||||
|
||||
// It may have been removed already in which case we should remove the COF link
|
||||
if (!gAgentWearables.isWearingItem(idItemBase))
|
||||
removeCOFItemLinks(idItemBase);
|
||||
}
|
||||
|
||||
void LLCOFMgr::synchWearables()
|
||||
{
|
||||
const LLUUID idCOF = getCOF();
|
||||
|
||||
// Grab all wearable links currently in COF
|
||||
LLInventoryModel::item_array_t items;
|
||||
getDescendentsOfAssetType(idCOF, items, LLAssetType::AT_BODYPART, true);
|
||||
getDescendentsOfAssetType(idCOF, items, LLAssetType::AT_CLOTHING, true);
|
||||
|
||||
// Transform collection of link LLViewerInventory pointers into collection of target LLUUIDs
|
||||
uuid_vec_t curItems;
|
||||
for (S32 idxItem = 0; idxItem < items.count(); idxItem++)
|
||||
{
|
||||
const LLViewerInventoryItem* pItem = items.get(idxItem);
|
||||
if (!pItem)
|
||||
continue;
|
||||
curItems.push_back(pItem->getLinkedUUID());
|
||||
}
|
||||
|
||||
// Grab the item UUIDs of all currently worn wearables
|
||||
uuid_vec_t newItems;
|
||||
for (S32 idxType = 0; idxType < LLWearableType::WT_COUNT; idxType++)
|
||||
{
|
||||
const LLUUID& idItem = gAgentWearables.getWearableItemID((LLWearableType::EType)idxType, 0); // TODO: MULTI-WEARABLE
|
||||
if (idItem.isNull())
|
||||
continue;
|
||||
newItems.push_back(idItem);
|
||||
}
|
||||
|
||||
uuid_vec_t addItems, remItems;
|
||||
LLCommonUtils::computeDifference(newItems, curItems, addItems, remItems);
|
||||
|
||||
// Add links for worn wearables that aren't linked yet
|
||||
for (uuid_vec_t::const_iterator itItem = addItems.begin(); itItem != addItems.end(); ++itItem)
|
||||
addWearable(*itItem);
|
||||
|
||||
// Remove links of wearables that aren't worn anymore
|
||||
for (uuid_vec_t::const_iterator itItem = remItems.begin(); itItem != remItems.end(); ++itItem)
|
||||
removeWearable(*itItem);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Base outfit folder functions
|
||||
//
|
||||
|
||||
void LLCOFMgr::addBOFLink(const LLUUID &idFolder, LLPointer<LLInventoryCallback> cb)
|
||||
{
|
||||
purgeBOFLink();
|
||||
|
||||
const LLViewerInventoryCategory* pFolder = gInventory.getCategory(idFolder);
|
||||
if ( (pFolder) && (LLFolderType::FT_OUTFIT == pFolder->getPreferredType()) )
|
||||
link_inventory_item(gAgent.getID(), idFolder, getCOF(), pFolder->getName(), "", LLAssetType::AT_LINK_FOLDER, cb);
|
||||
}
|
||||
|
||||
void LLCOFMgr::purgeBOFLink()
|
||||
{
|
||||
LLInventoryModel::cat_array_t* pFolders; LLInventoryModel::item_array_t* pItems;
|
||||
gInventory.getDirectDescendentsOf(getCOF(), pFolders, pItems);
|
||||
for (S32 idxItem = 0, cntItem = pItems->count(); idxItem < cntItem; idxItem++)
|
||||
{
|
||||
const LLViewerInventoryItem* pItem = pItems->get(idxItem).get();
|
||||
if ( (!pItem) || (LLAssetType::AT_LINK_FOLDER != pItem->getActualType()) )
|
||||
continue;
|
||||
|
||||
const LLViewerInventoryCategory* pLinkFolder = pItem->getLinkedCategory();
|
||||
if ( (pLinkFolder) && (LLFolderType::FT_OUTFIT == pLinkFolder->getPreferredType()) )
|
||||
gInventory.purgeObject(pItem->getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
@@ -1,90 +0,0 @@
|
||||
/**
|
||||
*
|
||||
* Copyright (c) 2010, Kitty Barnett
|
||||
*
|
||||
* The source code in this file is provided to you under the terms of the
|
||||
* GNU General Public License, version 2.0, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. Terms of the GPL can be found in doc/GPL-license.txt
|
||||
* in this distribution, or online at http://www.gnu.org/licenses/gpl-2.0.txt
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge that
|
||||
* you have read and understood your obligations described above, and agree to
|
||||
* abide by those obligations.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "llinventorymodel.h"
|
||||
#include "llmemory.h"
|
||||
#include "llviewerinventory.h"
|
||||
|
||||
// ============================================================================
|
||||
|
||||
class LLCOFMgr : public LLSingleton<LLCOFMgr>
|
||||
{
|
||||
/*
|
||||
* Helper functions
|
||||
*/
|
||||
public:
|
||||
void checkCOF();
|
||||
void fetchCOF();
|
||||
static const LLUUID getCOF() { return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT); }
|
||||
static void getDescendentsOfAssetType(const LLUUID& idCat, LLInventoryModel::item_array_t& items,
|
||||
LLAssetType::EType typeAsset, bool fFollowFolderLinks);
|
||||
bool isLinkInCOF(const LLUUID& idItem) const;
|
||||
BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
|
||||
protected:
|
||||
void addCOFItemLink(const LLUUID& idItem, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
void addCOFItemLink(const LLInventoryItem* pItem, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
void removeCOFItemLinks(const LLUUID& idItem);
|
||||
|
||||
/*
|
||||
* Attachment functions
|
||||
*/
|
||||
public:
|
||||
void addAttachment(const LLUUID& idItem);
|
||||
void removeAttachment(const LLUUID& idItem);
|
||||
void synchAttachments();
|
||||
protected:
|
||||
void onLinkAttachmentComplete(const LLUUID& idItem);
|
||||
void linkPendingAttachments();
|
||||
void setLinkAttachments(bool fEnable);
|
||||
void updateAttachments();
|
||||
|
||||
/*
|
||||
* Wearable functions
|
||||
*/
|
||||
public:
|
||||
void addWearable(const LLUUID& idItem);
|
||||
void removeWearable(const LLUUID& idItem);
|
||||
void synchWearables();
|
||||
protected:
|
||||
void onLinkWearableComplete(const LLUUID& idItem);
|
||||
|
||||
/*
|
||||
* Base outfit folder functions
|
||||
*/
|
||||
public:
|
||||
void addBOFLink(const LLUUID& idFolder, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
void purgeBOFLink();
|
||||
|
||||
/*
|
||||
* Member variables
|
||||
*/
|
||||
protected:
|
||||
bool m_fLinkAttachments;
|
||||
uuid_vec_t m_PendingAttachLinks;
|
||||
uuid_vec_t m_PendingWearableLinks;
|
||||
|
||||
protected:
|
||||
LLCOFMgr() : m_fLinkAttachments(false) {}
|
||||
private:
|
||||
friend class LLCOFFetcher;
|
||||
friend class LLCOFLinkTargetFetcher;
|
||||
friend class LLDeferredAddLinkTargetFetcher;
|
||||
friend class LLLinkAttachmentCallback;
|
||||
friend class LLLinkWearableCallback;
|
||||
friend class LLSingleton<LLCOFMgr>;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
@@ -81,10 +81,6 @@ DOHexEditor::DOHexEditor(const std::string& name, const LLRect& rect)
|
||||
DOHexEditor::~DOHexEditor()
|
||||
{
|
||||
gFocusMgr.releaseFocusIfNeeded(this);
|
||||
if(gEditMenuHandler == this)
|
||||
{
|
||||
gEditMenuHandler = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
LLView* DOHexEditor::fromXML(LLXMLNodePtr node, LLView *parent, class LLUICtrlFactory *factory)
|
||||
@@ -273,7 +269,8 @@ U32 DOHexEditor::getProperSelectionEnd()
|
||||
|
||||
BOOL DOHexEditor::handleScrollWheel(S32 x, S32 y, S32 clicks)
|
||||
{
|
||||
return mScrollbar->handleScrollWheel( 0, 0, clicks );
|
||||
mScrollbar->handleScrollWheel( 0, 0, clicks );
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL DOHexEditor::handleMouseDown(S32 x, S32 y, MASK mask)
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
#include "roles_constants.h"
|
||||
#include "llviewerregion.h"
|
||||
|
||||
#include "llpanelinventory.h"
|
||||
#include "llpanelobjectinventory.h"
|
||||
#include "llinventorybridge.h"
|
||||
|
||||
#include "llboost.h"
|
||||
|
||||
@@ -670,8 +670,10 @@ void LocalAssetBrowser::PerformTimedActions(void)
|
||||
// one of the layer bitmaps has been updated, we need to rebake.
|
||||
if ( mLayerUpdated )
|
||||
{
|
||||
LLVOAvatar* avatar = gAgentAvatarp;
|
||||
if (avatar) { avatar->forceBakeAllTextures(SLAM_FOR_DEBUG); }
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
gAgentAvatarp->forceBakeAllTextures(SLAM_FOR_DEBUG);
|
||||
}
|
||||
|
||||
mLayerUpdated = false;
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ void LLFloaterSculptPreview::draw()
|
||||
|
||||
if (selected <= 0)
|
||||
{
|
||||
gl_rect_2d_checkerboard(getScreenRect(),mPreviewRect);
|
||||
gl_rect_2d_checkerboard(calcScreenRect(),mPreviewRect);
|
||||
LLGLDisable gls_alpha(GL_ALPHA_TEST);
|
||||
|
||||
if(mImagep.notNull())
|
||||
|
||||
@@ -65,6 +65,11 @@ class HippoFloaterXmlImpl : public LLFloater
|
||||
private:
|
||||
std::string mName;
|
||||
bool mIsNotifyOnClose;
|
||||
//Must retain handles to unregister notices.
|
||||
typedef boost::signals2::scoped_connection notice_connection_t;
|
||||
typedef boost::shared_ptr<notice_connection_t> notice_ptr_t;
|
||||
|
||||
std::map<LLUICtrl*, notice_ptr_t > mNotices;
|
||||
};
|
||||
|
||||
|
||||
@@ -260,7 +265,7 @@ void HippoFloaterXml::execute(const std::string &cmds)
|
||||
// ********************************************************************
|
||||
// generic notification callbacks
|
||||
|
||||
static void notify(LLUICtrl *ctrl, void *data)
|
||||
static void notifyCallback(LLUICtrl *ctrl)
|
||||
{
|
||||
std::string msg = "NOTIFY:";
|
||||
msg += ctrl->getName();
|
||||
@@ -269,11 +274,6 @@ static void notify(LLUICtrl *ctrl, void *data)
|
||||
send_chat_from_viewer(msg, CHAT_TYPE_WHISPER, CHANNEL);
|
||||
}
|
||||
|
||||
static void notify(void *data)
|
||||
{
|
||||
notify(static_cast<LLUICtrl*>(data), 0);
|
||||
}
|
||||
|
||||
void HippoFloaterXmlImpl::onClose(bool quitting)
|
||||
{
|
||||
if (mIsNotifyOnClose)
|
||||
@@ -324,16 +324,19 @@ bool HippoFloaterXmlImpl::execute(LLUICtrl *ctrl,
|
||||
bool set = (value != "0");
|
||||
if (HippoFloaterXmlImpl *floater = dynamic_cast<HippoFloaterXmlImpl*>(ctrl)) {
|
||||
floater->mIsNotifyOnClose = set;
|
||||
} else if (LLButton *button = dynamic_cast<LLButton*>(ctrl)) {
|
||||
} else if (LLButton *button = dynamic_cast<LLButton*>(ctrl))
|
||||
{
|
||||
if (set)
|
||||
button->setClickedCallback(notify, ctrl);
|
||||
floater->mNotices[button] = notice_ptr_t(new notice_connection_t(button->setClickedCallback(boost::bind(¬ifyCallback, ctrl))));
|
||||
else
|
||||
button->setClickedCallback(0, 0);
|
||||
} else {
|
||||
floater->mNotices.erase(button);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (set)
|
||||
ctrl->setCommitCallback(notify);
|
||||
floater->mNotices[ctrl] = notice_ptr_t(new notice_connection_t(ctrl->setCommitCallback(boost::bind(¬ifyCallback, ctrl))));
|
||||
else
|
||||
ctrl->setCommitCallback(0);
|
||||
floater->mNotices.erase(ctrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3698,12 +3698,6 @@ void LLAgent::setTeleportState(ETeleportState state)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// [RLVa:KB] - Alternate: Snowglobe-1.2.4 | Version: 1.23.4 | Checked: 2009-07-07 (RLVa-1.0.0d) | Added: RLVa-0.2.0b
|
||||
if ( (rlv_handler_t::isEnabled()) && (TELEPORT_NONE == mTeleportState) )
|
||||
{
|
||||
gRlvHandler.setCanCancelTp(true);
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
}
|
||||
|
||||
void LLAgent::stopCurrentAnimations()
|
||||
@@ -3840,12 +3834,11 @@ void LLAgent::sendAgentSetAppearance()
|
||||
{
|
||||
if (!isAgentAvatarValid()) return;
|
||||
|
||||
if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && !gAgentCamera.cameraCustomizeAvatar()))
|
||||
if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
llinfos << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << llendl;
|
||||
//dumpAvatarTEs( "sendAgentSetAppearance()" );
|
||||
|
||||
@@ -3875,7 +3868,7 @@ void LLAgent::sendAgentSetAppearance()
|
||||
|
||||
// is texture data current relative to wearables?
|
||||
// KLW - TAT this will probably need to check the local queue.
|
||||
BOOL textures_current = !gAgentAvatarp->hasPendingBakedUploads() && gAgentWearables.areWearablesLoaded();
|
||||
BOOL textures_current = gAgentAvatarp->areTexturesCurrent();
|
||||
|
||||
for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
|
||||
{
|
||||
@@ -3887,8 +3880,8 @@ void LLAgent::sendAgentSetAppearance()
|
||||
continue;
|
||||
}
|
||||
|
||||
// IMG_DEFAULT_AVATAR means not baked
|
||||
if (!gAgentAvatarp->isTextureDefined(texture_index))
|
||||
// IMG_DEFAULT_AVATAR means not baked. 0 index should be ignored for baked textures
|
||||
if (!gAgentAvatarp->isTextureDefined(texture_index, 0))
|
||||
{
|
||||
textures_current = FALSE;
|
||||
break;
|
||||
@@ -3901,12 +3894,17 @@ void LLAgent::sendAgentSetAppearance()
|
||||
llinfos << "TAT: Sending cached texture data" << llendl;
|
||||
for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
|
||||
{
|
||||
BOOL generate_valid_hash = TRUE;
|
||||
if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index))
|
||||
{
|
||||
generate_valid_hash = FALSE;
|
||||
llinfos << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << llendl;
|
||||
}
|
||||
|
||||
const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, true);
|
||||
const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash);
|
||||
if (hash.notNull())
|
||||
{
|
||||
const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
|
||||
|
||||
ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
|
||||
msg->nextBlockFast(_PREHASH_WearableData);
|
||||
msg->addUUIDFast(_PREHASH_CacheID, hash);
|
||||
msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
|
||||
|
||||
@@ -2392,7 +2392,7 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came
|
||||
gFocusMgr.setKeyboardFocus( NULL );
|
||||
gFocusMgr.setMouseCapture( NULL );
|
||||
|
||||
LLVOAvatar::onCustomizeStart();
|
||||
LLVOAvatarSelf::onCustomizeStart();
|
||||
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
@@ -2418,10 +2418,11 @@ void LLAgentCamera::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL came
|
||||
{
|
||||
setAnimationDuration(gSavedSettings.getF32("ZoomTime"));
|
||||
}
|
||||
//gAgentAvatarp->invalidateAll();
|
||||
//gAgentAvatarp->updateMeshTextures();
|
||||
}
|
||||
|
||||
gAgentAvatarp->invalidateAll();
|
||||
gAgentAvatarp->updateMeshTextures();
|
||||
|
||||
gAgentCamera.setFocusGlobal(LLVector3d::zero);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,33 +2,26 @@
|
||||
* @file llagentwearables.h
|
||||
* @brief LLAgentWearables class header file
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-2010, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlife.com/developers/opensource/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlife.com/developers/opensource/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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_LLAGENTWEARABLES_H
|
||||
@@ -63,16 +56,16 @@ public:
|
||||
LLAgentWearables();
|
||||
virtual ~LLAgentWearables();
|
||||
void setAvatarObject(LLVOAvatarSelf *avatar);
|
||||
void createStandardWearables(BOOL female);
|
||||
void createStandardWearables();
|
||||
void cleanup();
|
||||
//void dump();
|
||||
void dump();
|
||||
|
||||
// LLInitClass interface
|
||||
static void initClass();
|
||||
protected:
|
||||
void createStandardWearablesDone(S32 type, U32 index/* = 0*/);
|
||||
void createStandardWearablesAllDone();
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Queries
|
||||
//--------------------------------------------------------------------
|
||||
@@ -83,18 +76,16 @@ public:
|
||||
|
||||
BOOL isWearableCopyable(LLWearableType::EType type, U32 index /*= 0*/) const;
|
||||
BOOL areWearablesLoaded() const;
|
||||
bool isCOFChangeInProgress() const { return mCOFChangeInProgress; }
|
||||
void updateWearablesLoaded();
|
||||
//void checkWearablesLoaded() const;
|
||||
//bool canMoveWearable(const LLUUID& item_id, bool closer_to_body);
|
||||
void checkWearablesLoaded() const;
|
||||
bool canMoveWearable(const LLUUID& item_id, bool closer_to_body);
|
||||
|
||||
// Note: False for shape, skin, eyes, and hair, unless you have MORE than 1.
|
||||
//bool canWearableBeRemoved(const LLWearable* wearable) const;
|
||||
bool canWearableBeRemoved(const LLWearable* wearable) const;
|
||||
|
||||
//void animateAllWearableParams(F32 delta, BOOL upload_bake);
|
||||
void animateAllWearableParams(F32 delta, BOOL upload_bake);
|
||||
|
||||
BOOL needsReplacement(LLWearableType::EType wearableType, S32 remove);
|
||||
//U32 getWearablePermMask(LLWearableType::EType type) const;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Accessors
|
||||
//--------------------------------------------------------------------
|
||||
@@ -109,11 +100,11 @@ public:
|
||||
LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/);
|
||||
const LLWearable* getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
|
||||
LLWearable* getTopWearable(const LLWearableType::EType type);
|
||||
LLWearable* getBottomWearable(const LLWearableType::EType type);
|
||||
LLWearable* getBottomWearable(const LLWearableType::EType type);
|
||||
U32 getWearableCount(const LLWearableType::EType type) const;
|
||||
U32 getWearableCount(const U32 tex_index) const;
|
||||
|
||||
static const U32 MAX_CLOTHING_PER_TYPE = 1;
|
||||
static const U32 MAX_CLOTHING_PER_TYPE = 5;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
@@ -129,31 +120,20 @@ private:
|
||||
void popWearable(const LLWearableType::EType type, U32 index);
|
||||
|
||||
public:
|
||||
void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable);
|
||||
void setWearableItem(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false);
|
||||
void setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove);
|
||||
void setWearableName(const LLUUID& item_id, const std::string& new_name);
|
||||
//void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index);
|
||||
void addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index);
|
||||
U32 getWearableIndex(const LLWearable *wearable) const;
|
||||
|
||||
protected:
|
||||
void setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable );
|
||||
void setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append = false);
|
||||
static bool onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable);
|
||||
|
||||
void addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
|
||||
LLWearable* wearable,
|
||||
const LLUUID& category_id = LLUUID::null,
|
||||
BOOL notify = TRUE);
|
||||
|
||||
/**
|
||||
* @brief Only public because of addWearableToAgentInventoryCallback.
|
||||
*
|
||||
* NOTE: Do not call this method unless you are the inventory callback.
|
||||
* NOTE: This can suffer from race conditions when working on the
|
||||
* same values for index.
|
||||
* @param index The index in mWearableEntry.
|
||||
* @param item_id The inventory item id of the new wearable to wear.
|
||||
* @param wearable The actual wearable data.
|
||||
*/
|
||||
void addWearabletoAgentInventoryDone(const LLWearableType::EType type,
|
||||
const U32 index,
|
||||
const LLUUID& item_id,
|
||||
@@ -166,15 +146,15 @@ protected:
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
//static void createWearable(LLWearableType::EType type, bool wear = false, const LLUUID& parent_id = LLUUID::null);
|
||||
//static void editWearable(const LLUUID& item_id);
|
||||
//bool moveWearable(const LLViewerInventoryItem* item, bool closer_to_body);
|
||||
static void createWearable(LLWearableType::EType type, bool wear = false, const LLUUID& parent_id = LLUUID::null);
|
||||
static void editWearable(const LLUUID& item_id);
|
||||
bool moveWearable(const LLViewerInventoryItem* item, bool closer_to_body);
|
||||
|
||||
//void requestEditingWearable(const LLUUID& item_id);
|
||||
//void editWearableIfRequested(const LLUUID& item_id);
|
||||
void requestEditingWearable(const LLUUID& item_id);
|
||||
void editWearableIfRequested(const LLUUID& item_id);
|
||||
|
||||
private:
|
||||
//LLUUID mItemToEdit;
|
||||
LLUUID mItemToEdit;
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Removing wearables
|
||||
@@ -185,7 +165,6 @@ private:
|
||||
void removeWearableFinal(const LLWearableType::EType type, bool do_remove_all /*= false*/, U32 index /*= 0*/);
|
||||
protected:
|
||||
static bool onRemoveWearableDialog(const LLSD& notification, const LLSD& response);
|
||||
static void userRemoveAllClothesStep2(BOOL proceed, void* userdata ); // userdata is NULL
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Server Communication
|
||||
@@ -201,7 +180,7 @@ protected:
|
||||
void sendAgentWearablesRequest();
|
||||
void queryWearableCache();
|
||||
void updateServer();
|
||||
static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata );
|
||||
static void onInitialWearableAssetArrived(LLWearable* wearable, void* userdata);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Outfits
|
||||
@@ -210,27 +189,20 @@ public:
|
||||
|
||||
// Should only be called if we *know* we've never done so before, since users may
|
||||
// not want the Library outfits to stay in their quick outfit selector and can delete them.
|
||||
//void populateMyOutfitsFolder();
|
||||
void makeNewOutfit(
|
||||
const std::string& new_folder_name,
|
||||
const LLDynamicArray<S32>& wearables_to_include,
|
||||
const LLDynamicArray<S32>& attachments_to_include,
|
||||
BOOL rename_clothing);
|
||||
private:
|
||||
void populateMyOutfitsFolder();
|
||||
|
||||
private:
|
||||
void makeNewOutfitDone(S32 type, U32 index);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Save Wearables
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found );
|
||||
void saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found);
|
||||
void saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE,
|
||||
const std::string new_name = "");
|
||||
|
||||
void saveAllWearables();
|
||||
void revertWearable( LLWearableType::EType type, const U32 index);
|
||||
void revertAllWearables();
|
||||
void revertWearable(const LLWearableType::EType type, const U32 index, bool set_by_user=false);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Static UI hooks
|
||||
@@ -238,15 +210,10 @@ public:
|
||||
public:
|
||||
static void userRemoveWearable(const LLWearableType::EType &type, const U32 &index);
|
||||
static void userRemoveWearablesOfType(const LLWearableType::EType &type);
|
||||
static void userRemoveAllClothes();
|
||||
|
||||
typedef std::vector<LLViewerObject*> llvo_vec_t;
|
||||
|
||||
// static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
|
||||
// [SL:KB] - Patch: Appearance-SyncAttach | Checked: 2010-09-22 (Catznip-2.2.0a) | Added: Catznip-2.2.0a
|
||||
// Not the best way to go about this but other attempts changed far too much LL code to be a viable solution
|
||||
static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array, bool fAttachOnly = false);
|
||||
// [/SL:KB]
|
||||
typedef std::vector<LLViewerObject*> llvo_vec_t;
|
||||
|
||||
static void userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
|
||||
static void userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
|
||||
static void userRemoveAllAttachments();
|
||||
static void userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
|
||||
@@ -258,7 +225,7 @@ public:
|
||||
// Signals
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
/*typedef boost::function<void()> loading_started_callback_t;
|
||||
typedef boost::function<void()> loading_started_callback_t;
|
||||
typedef boost::signals2::signal<void()> loading_started_signal_t;
|
||||
boost::signals2::connection addLoadingStartedCallback(loading_started_callback_t cb);
|
||||
|
||||
@@ -267,9 +234,11 @@ public:
|
||||
boost::signals2::connection addLoadedCallback(loaded_callback_t cb);
|
||||
|
||||
void notifyLoadingStarted();
|
||||
void notifyLoadingFinished();*/
|
||||
void notifyLoadingFinished();
|
||||
|
||||
private:
|
||||
loading_started_signal_t mLoadingStartedSignal; // should be called before wearables are changed
|
||||
loaded_signal_t mLoadedSignal; // emitted when all agent wearables get loaded
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Member variables
|
||||
@@ -281,6 +250,12 @@ private:
|
||||
|
||||
static BOOL mInitialWearablesUpdateReceived;
|
||||
BOOL mWearablesLoaded;
|
||||
std::set<LLUUID> mItemsAwaitingWearableUpdate;
|
||||
|
||||
/**
|
||||
* True if agent's outfit is being changed now.
|
||||
*/
|
||||
BOOL mCOFChangeInProgress;
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// Support classes
|
||||
@@ -300,31 +275,22 @@ private:
|
||||
class addWearableToAgentInventoryCallback : public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
enum ETodo
|
||||
{
|
||||
CALL_NONE = 0,
|
||||
CALL_UPDATE = 1,
|
||||
CALL_RECOVERDONE = 2,
|
||||
CALL_CREATESTANDARDDONE = 4,
|
||||
CALL_MAKENEWOUTFITDONE = 8
|
||||
} EType;
|
||||
CALL_MAKENEWOUTFITDONE = 8,
|
||||
CALL_WEARITEM = 16
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Construct a callback for dealing with the wearables.
|
||||
*
|
||||
* Would like to pass the agent in here, but we can't safely
|
||||
* count on it being around later. Just use gAgent directly.
|
||||
* @param cb callback to execute on completion (??? unused ???)
|
||||
* @param index Index for the wearable in the agent
|
||||
* @param wearable The wearable data.
|
||||
* @param todo Bitmask of actions to take on completion.
|
||||
*/
|
||||
addWearableToAgentInventoryCallback(LLPointer<LLRefCount> cb,
|
||||
LLWearableType::EType type,
|
||||
U32 index,
|
||||
LLWearable* wearable,
|
||||
U32 todo = CALL_NONE);
|
||||
virtual void fire(const LLUUID& inv_item);
|
||||
|
||||
private:
|
||||
LLWearableType::EType mType;
|
||||
U32 mIndex;
|
||||
|
||||
607
indra/newview/llagentwearablesfetch.cpp
Normal file
607
indra/newview/llagentwearablesfetch.cpp
Normal file
@@ -0,0 +1,607 @@
|
||||
/**
|
||||
* @file llagentwearablesfetch.cpp
|
||||
* @brief LLAgentWearblesFetch class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&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 "llagentwearablesfetch.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llstartup.h"
|
||||
#include "llvoavatarself.h"
|
||||
|
||||
|
||||
class LLOrderMyOutfitsOnDestroy: public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
LLOrderMyOutfitsOnDestroy() {};
|
||||
|
||||
virtual ~LLOrderMyOutfitsOnDestroy()
|
||||
{
|
||||
if (!LLApp::isRunning())
|
||||
{
|
||||
llwarns << "called during shutdown, skipping" << llendl;
|
||||
return;
|
||||
}
|
||||
|
||||
const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
|
||||
if (my_outfits_id.isNull()) return;
|
||||
|
||||
LLInventoryModel::cat_array_t* cats;
|
||||
LLInventoryModel::item_array_t* items;
|
||||
gInventory.getDirectDescendentsOf(my_outfits_id, cats, items);
|
||||
if (!cats) return;
|
||||
|
||||
//My Outfits should at least contain saved initial outfit and one another outfit
|
||||
if (cats->size() < 2)
|
||||
{
|
||||
llwarning("My Outfits category was not populated properly", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
llinfos << "Starting updating My Outfits with wearables ordering information" << llendl;
|
||||
|
||||
for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin();
|
||||
outfit_iter != cats->end(); ++outfit_iter)
|
||||
{
|
||||
const LLUUID& cat_id = (*outfit_iter)->getUUID();
|
||||
if (cat_id.isNull()) continue;
|
||||
|
||||
// saved initial outfit already contains wearables ordering information
|
||||
if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue;
|
||||
|
||||
LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id);
|
||||
}
|
||||
|
||||
llinfos << "Finished updating My Outfits with wearables ordering information" << llendl;
|
||||
}
|
||||
|
||||
/* virtual */ void fire(const LLUUID& inv_item) {};
|
||||
};
|
||||
|
||||
|
||||
LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :
|
||||
LLInventoryFetchDescendentsObserver(cof_id)
|
||||
{
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
gAgentAvatarp->outputRezTiming("Initial wearables fetch started");
|
||||
}
|
||||
}
|
||||
|
||||
LLInitialWearablesFetch::~LLInitialWearablesFetch()
|
||||
{
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLInitialWearablesFetch::done()
|
||||
{
|
||||
// Delay processing the actual results of this so it's not handled within
|
||||
// gInventory.notifyObservers. The results will be handled in the next
|
||||
// idle tick instead.
|
||||
gInventory.removeObserver(this);
|
||||
doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this));
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
gAgentAvatarp->outputRezTiming("Initial wearables fetch done");
|
||||
}
|
||||
}
|
||||
|
||||
void LLInitialWearablesFetch::add(InitialWearableData &data)
|
||||
|
||||
{
|
||||
mAgentInitialWearables.push_back(data);
|
||||
}
|
||||
|
||||
void LLInitialWearablesFetch::processContents()
|
||||
{
|
||||
if(!gAgentAvatarp) //no need to process wearables if the agent avatar is deleted.
|
||||
{
|
||||
delete this;
|
||||
return ;
|
||||
}
|
||||
|
||||
// Fetch the wearable items from the Current Outfit Folder
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
LLFindWearables is_wearable;
|
||||
llassert_always(mComplete.size() != 0);
|
||||
gInventory.collectDescendentsIf(mComplete.front(), cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH, is_wearable);
|
||||
|
||||
LLAppearanceMgr::instance().setAttachmentInvLinkEnable(true);
|
||||
if (wearable_array.count() > 0)
|
||||
{
|
||||
gAgentWearables.notifyLoadingStarted();
|
||||
LLAppearanceMgr::instance().updateAppearanceFromCOF();
|
||||
}
|
||||
else
|
||||
{
|
||||
// if we're constructing the COF from the wearables message, we don't have a proper outfit link
|
||||
LLAppearanceMgr::instance().setOutfitDirty(true);
|
||||
processWearablesMessage();
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
class LLFetchAndLinkObserver: public LLInventoryFetchItemsObserver
|
||||
{
|
||||
public:
|
||||
LLFetchAndLinkObserver(uuid_vec_t& ids):
|
||||
LLInventoryFetchItemsObserver(ids)
|
||||
{
|
||||
}
|
||||
~LLFetchAndLinkObserver()
|
||||
{
|
||||
}
|
||||
virtual void done()
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
|
||||
// Link to all fetched items in COF.
|
||||
LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
|
||||
for (uuid_vec_t::iterator it = mIDs.begin();
|
||||
it != mIDs.end();
|
||||
++it)
|
||||
{
|
||||
LLUUID id = *it;
|
||||
LLViewerInventoryItem *item = gInventory.getItem(*it);
|
||||
if (!item)
|
||||
{
|
||||
llwarns << "fetch failed!" << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
link_inventory_item(gAgent.getID(),
|
||||
item->getLinkedUUID(),
|
||||
LLAppearanceMgr::instance().getCOF(),
|
||||
item->getName(),
|
||||
item->getDescription(),
|
||||
LLAssetType::AT_LINK,
|
||||
link_waiter);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void LLInitialWearablesFetch::processWearablesMessage()
|
||||
{
|
||||
if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead.
|
||||
{
|
||||
const LLUUID current_outfit_id = LLAppearanceMgr::instance().getCOF();
|
||||
uuid_vec_t ids;
|
||||
for (U8 i = 0; i < mAgentInitialWearables.size(); ++i)
|
||||
{
|
||||
// Populate the current outfit folder with links to the wearables passed in the message
|
||||
InitialWearableData *wearable_data = new InitialWearableData(mAgentInitialWearables[i]); // This will be deleted in the callback.
|
||||
|
||||
if (wearable_data->mAssetID.notNull())
|
||||
{
|
||||
ids.push_back(wearable_data->mItemID);
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "Invalid wearable, type " << wearable_data->mType << " itemID "
|
||||
<< wearable_data->mItemID << " assetID " << wearable_data->mAssetID << llendl;
|
||||
delete wearable_data;
|
||||
}
|
||||
}
|
||||
|
||||
// Add all current attachments to the requested items as well.
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
for (LLVOAvatar::attachment_map_t::const_iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
|
||||
iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter)
|
||||
{
|
||||
LLViewerJointAttachment* attachment = iter->second;
|
||||
if (!attachment) continue;
|
||||
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
|
||||
attachment_iter != attachment->mAttachedObjects.end();
|
||||
++attachment_iter)
|
||||
{
|
||||
LLViewerObject* attached_object = (*attachment_iter);
|
||||
if (!attached_object) continue;
|
||||
const LLUUID& item_id = attached_object->getAttachmentItemID();
|
||||
if (item_id.isNull()) continue;
|
||||
ids.push_back(item_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Need to fetch the inventory items for ids, then create links to them after they arrive.
|
||||
LLFetchAndLinkObserver *fetcher = new LLFetchAndLinkObserver(ids);
|
||||
fetcher->startFetch();
|
||||
// If no items to be fetched, done will never be triggered.
|
||||
// TODO: Change LLInventoryFetchItemsObserver::fetchItems to trigger done() on this condition.
|
||||
if (fetcher->isFinished())
|
||||
{
|
||||
fetcher->done();
|
||||
}
|
||||
else
|
||||
{
|
||||
gInventory.addObserver(fetcher);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_WARNS("Wearables") << "No current outfit folder items found and no initial wearables fallback message received." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
LLLibraryOutfitsFetch::LLLibraryOutfitsFetch(const LLUUID& my_outfits_id) :
|
||||
LLInventoryFetchDescendentsObserver(my_outfits_id),
|
||||
mCurrFetchStep(LOFS_FOLDER),
|
||||
mOutfitsPopulated(false)
|
||||
{
|
||||
llinfos << "created" << llendl;
|
||||
|
||||
mMyOutfitsID = LLUUID::null;
|
||||
mClothingID = LLUUID::null;
|
||||
mLibraryClothingID = LLUUID::null;
|
||||
mImportedClothingID = LLUUID::null;
|
||||
mImportedClothingName = "Imported Library Clothing";
|
||||
}
|
||||
|
||||
LLLibraryOutfitsFetch::~LLLibraryOutfitsFetch()
|
||||
{
|
||||
llinfos << "destroyed" << llendl;
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::done()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
// Delay this until idle() routine, since it's a heavy operation and
|
||||
// we also can't have it run within notifyObservers.
|
||||
doOnIdleOneTime(boost::bind(&LLLibraryOutfitsFetch::doneIdle,this));
|
||||
gInventory.removeObserver(this); // Prevent doOnIdleOneTime from being added twice.
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::doneIdle()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
gInventory.addObserver(this); // Add this back in since it was taken out during ::done()
|
||||
|
||||
switch (mCurrFetchStep)
|
||||
{
|
||||
case LOFS_FOLDER:
|
||||
folderDone();
|
||||
mCurrFetchStep = LOFS_OUTFITS;
|
||||
break;
|
||||
case LOFS_OUTFITS:
|
||||
outfitsDone();
|
||||
mCurrFetchStep = LOFS_LIBRARY;
|
||||
break;
|
||||
case LOFS_LIBRARY:
|
||||
libraryDone();
|
||||
mCurrFetchStep = LOFS_IMPORTED;
|
||||
break;
|
||||
case LOFS_IMPORTED:
|
||||
importedFolderDone();
|
||||
mCurrFetchStep = LOFS_CONTENTS;
|
||||
break;
|
||||
case LOFS_CONTENTS:
|
||||
contentsDone();
|
||||
break;
|
||||
default:
|
||||
llwarns << "Got invalid state for outfit fetch: " << mCurrFetchStep << llendl;
|
||||
mOutfitsPopulated = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
// We're completely done. Cleanup.
|
||||
if (mOutfitsPopulated)
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
delete this;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::folderDone()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
gInventory.collectDescendents(mMyOutfitsID, cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
// Early out if we already have items in My Outfits
|
||||
// except the case when My Outfits contains just initial outfit
|
||||
if (cat_array.count() > 1)
|
||||
{
|
||||
mOutfitsPopulated = true;
|
||||
return;
|
||||
}
|
||||
|
||||
mClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
|
||||
mLibraryClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true);
|
||||
|
||||
// If Library->Clothing->Initial Outfits exists, use that.
|
||||
LLNameCategoryCollector matchFolderFunctor("Initial Outfits");
|
||||
cat_array.clear();
|
||||
gInventory.collectDescendentsIf(mLibraryClothingID,
|
||||
cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
matchFolderFunctor);
|
||||
if (cat_array.count() > 0)
|
||||
{
|
||||
const LLViewerInventoryCategory *cat = cat_array.get(0);
|
||||
mLibraryClothingID = cat->getUUID();
|
||||
}
|
||||
|
||||
mComplete.clear();
|
||||
|
||||
// Get the complete information on the items in the inventory.
|
||||
uuid_vec_t folders;
|
||||
folders.push_back(mClothingID);
|
||||
folders.push_back(mLibraryClothingID);
|
||||
setFetchIDs(folders);
|
||||
startFetch();
|
||||
if (isFinished())
|
||||
{
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::outfitsDone()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
uuid_vec_t folders;
|
||||
|
||||
// Collect the contents of the Library's Clothing folder
|
||||
gInventory.collectDescendents(mLibraryClothingID, cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
llassert(cat_array.count() > 0);
|
||||
for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin();
|
||||
iter != cat_array.end();
|
||||
++iter)
|
||||
{
|
||||
const LLViewerInventoryCategory *cat = iter->get();
|
||||
|
||||
// Get the names and id's of every outfit in the library, skip "Ruth"
|
||||
// because it's a low quality legacy outfit
|
||||
if (cat->getName() != "Ruth")
|
||||
{
|
||||
// Get the name of every outfit in the library
|
||||
folders.push_back(cat->getUUID());
|
||||
mLibraryClothingFolders.push_back(cat->getUUID());
|
||||
}
|
||||
}
|
||||
cat_array.clear();
|
||||
wearable_array.clear();
|
||||
|
||||
// Check if you already have an "Imported Library Clothing" folder
|
||||
LLNameCategoryCollector matchFolderFunctor(mImportedClothingName);
|
||||
gInventory.collectDescendentsIf(mClothingID,
|
||||
cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
matchFolderFunctor);
|
||||
if (cat_array.size() > 0)
|
||||
{
|
||||
const LLViewerInventoryCategory *cat = cat_array.get(0);
|
||||
mImportedClothingID = cat->getUUID();
|
||||
}
|
||||
|
||||
mComplete.clear();
|
||||
setFetchIDs(folders);
|
||||
startFetch();
|
||||
if (isFinished())
|
||||
{
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
class LLLibraryOutfitsCopyDone: public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
LLLibraryOutfitsCopyDone(LLLibraryOutfitsFetch * fetcher):
|
||||
mFireCount(0), mLibraryOutfitsFetcher(fetcher)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~LLLibraryOutfitsCopyDone()
|
||||
{
|
||||
if (!LLApp::isExiting() && mLibraryOutfitsFetcher)
|
||||
{
|
||||
gInventory.addObserver(mLibraryOutfitsFetcher);
|
||||
mLibraryOutfitsFetcher->done();
|
||||
}
|
||||
}
|
||||
|
||||
/* virtual */ void fire(const LLUUID& inv_item)
|
||||
{
|
||||
mFireCount++;
|
||||
}
|
||||
private:
|
||||
U32 mFireCount;
|
||||
LLLibraryOutfitsFetch * mLibraryOutfitsFetcher;
|
||||
};
|
||||
|
||||
// Copy the clothing folders from the library into the imported clothing folder
|
||||
void LLLibraryOutfitsFetch::libraryDone()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
if (mImportedClothingID != LLUUID::null)
|
||||
{
|
||||
// Skip straight to fetching the contents of the imported folder
|
||||
importedFolderFetch();
|
||||
return;
|
||||
}
|
||||
|
||||
// Remove observer; next autopopulation step will be triggered externally by LLLibraryOutfitsCopyDone.
|
||||
gInventory.removeObserver(this);
|
||||
|
||||
LLPointer<LLInventoryCallback> copy_waiter = new LLLibraryOutfitsCopyDone(this);
|
||||
mImportedClothingID = gInventory.createNewCategory(mClothingID,
|
||||
LLFolderType::FT_NONE,
|
||||
mImportedClothingName);
|
||||
// Copy each folder from library into clothing unless it already exists.
|
||||
for (uuid_vec_t::const_iterator iter = mLibraryClothingFolders.begin();
|
||||
iter != mLibraryClothingFolders.end();
|
||||
++iter)
|
||||
{
|
||||
const LLUUID& src_folder_id = (*iter); // Library clothing folder ID
|
||||
const LLViewerInventoryCategory *cat = gInventory.getCategory(src_folder_id);
|
||||
if (!cat)
|
||||
{
|
||||
llwarns << "Library folder import for uuid:" << src_folder_id << " failed to find folder." << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!LLAppearanceMgr::getInstance()->getCanMakeFolderIntoOutfit(src_folder_id))
|
||||
{
|
||||
llinfos << "Skipping non-outfit folder name:" << cat->getName() << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Don't copy the category if it already exists.
|
||||
LLNameCategoryCollector matchFolderFunctor(cat->getName());
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
gInventory.collectDescendentsIf(mImportedClothingID,
|
||||
cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH,
|
||||
matchFolderFunctor);
|
||||
if (cat_array.size() > 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LLUUID dst_folder_id = gInventory.createNewCategory(mImportedClothingID,
|
||||
LLFolderType::FT_NONE,
|
||||
cat->getName());
|
||||
LLAppearanceMgr::getInstance()->shallowCopyCategoryContents(src_folder_id, dst_folder_id, copy_waiter);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::importedFolderFetch()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
// Fetch the contents of the Imported Clothing Folder
|
||||
uuid_vec_t folders;
|
||||
folders.push_back(mImportedClothingID);
|
||||
|
||||
mComplete.clear();
|
||||
setFetchIDs(folders);
|
||||
startFetch();
|
||||
if (isFinished())
|
||||
{
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::importedFolderDone()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
uuid_vec_t folders;
|
||||
|
||||
// Collect the contents of the Imported Clothing folder
|
||||
gInventory.collectDescendents(mImportedClothingID, cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin();
|
||||
iter != cat_array.end();
|
||||
++iter)
|
||||
{
|
||||
const LLViewerInventoryCategory *cat = iter->get();
|
||||
|
||||
// Get the name of every imported outfit
|
||||
folders.push_back(cat->getUUID());
|
||||
mImportedClothingFolders.push_back(cat->getUUID());
|
||||
}
|
||||
|
||||
mComplete.clear();
|
||||
setFetchIDs(folders);
|
||||
startFetch();
|
||||
if (isFinished())
|
||||
{
|
||||
done();
|
||||
}
|
||||
}
|
||||
|
||||
void LLLibraryOutfitsFetch::contentsDone()
|
||||
{
|
||||
llinfos << "start" << llendl;
|
||||
|
||||
LLInventoryModel::cat_array_t cat_array;
|
||||
LLInventoryModel::item_array_t wearable_array;
|
||||
|
||||
LLPointer<LLOrderMyOutfitsOnDestroy> order_myoutfits_on_destroy = new LLOrderMyOutfitsOnDestroy;
|
||||
|
||||
for (uuid_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin();
|
||||
folder_iter != mImportedClothingFolders.end();
|
||||
++folder_iter)
|
||||
{
|
||||
const LLUUID &folder_id = (*folder_iter);
|
||||
const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
|
||||
if (!cat)
|
||||
{
|
||||
llwarns << "Library folder import for uuid:" << folder_id << " failed to find folder." << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
//initial outfit should be already in My Outfits
|
||||
if (cat->getName() == LLStartUp::getInitialOutfitName()) continue;
|
||||
|
||||
// First, make a folder in the My Outfits directory.
|
||||
LLUUID new_outfit_folder_id = gInventory.createNewCategory(mMyOutfitsID, LLFolderType::FT_OUTFIT, cat->getName());
|
||||
|
||||
cat_array.clear();
|
||||
wearable_array.clear();
|
||||
// Collect the contents of each imported clothing folder, so we can create new outfit links for it
|
||||
gInventory.collectDescendents(folder_id, cat_array, wearable_array,
|
||||
LLInventoryModel::EXCLUDE_TRASH);
|
||||
|
||||
for (LLInventoryModel::item_array_t::const_iterator wearable_iter = wearable_array.begin();
|
||||
wearable_iter != wearable_array.end();
|
||||
++wearable_iter)
|
||||
{
|
||||
const LLViewerInventoryItem *item = wearable_iter->get();
|
||||
link_inventory_item(gAgent.getID(),
|
||||
item->getLinkedUUID(),
|
||||
new_outfit_folder_id,
|
||||
item->getName(),
|
||||
item->getDescription(),
|
||||
LLAssetType::AT_LINK,
|
||||
order_myoutfits_on_destroy);
|
||||
}
|
||||
}
|
||||
|
||||
mOutfitsPopulated = true;
|
||||
}
|
||||
|
||||
114
indra/newview/llagentwearablesfetch.h
Normal file
114
indra/newview/llagentwearablesfetch.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
* @file llagentwearablesinitialfetch.h
|
||||
* @brief LLAgentWearablesInitialFetch class header file
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&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_LLAGENTWEARABLESINITIALFETCH_H
|
||||
#define LL_LLAGENTWEARABLESINITIALFETCH_H
|
||||
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llwearabletype.h"
|
||||
#include "lluuid.h"
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// InitialWearablesFetch
|
||||
//
|
||||
// This grabs contents from the COF and processes them.
|
||||
// The processing is handled in idle(), i.e. outside of done(),
|
||||
// to avoid gInventory.notifyObservers recursion.
|
||||
//--------------------------------------------------------------------
|
||||
class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver
|
||||
{
|
||||
LOG_CLASS(LLInitialWearablesFetch);
|
||||
|
||||
public:
|
||||
LLInitialWearablesFetch(const LLUUID& cof_id);
|
||||
~LLInitialWearablesFetch();
|
||||
virtual void done();
|
||||
|
||||
struct InitialWearableData
|
||||
{
|
||||
LLWearableType::EType mType;
|
||||
LLUUID mItemID;
|
||||
LLUUID mAssetID;
|
||||
InitialWearableData(LLWearableType::EType type, LLUUID& itemID, LLUUID& assetID) :
|
||||
mType(type),
|
||||
mItemID(itemID),
|
||||
mAssetID(assetID)
|
||||
{}
|
||||
};
|
||||
|
||||
void add(InitialWearableData &data);
|
||||
|
||||
protected:
|
||||
void processWearablesMessage();
|
||||
void processContents();
|
||||
|
||||
private:
|
||||
typedef std::vector<InitialWearableData> initial_wearable_data_vec_t;
|
||||
initial_wearable_data_vec_t mAgentInitialWearables; // Wearables from the old agent wearables msg
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// InitialWearablesFetch
|
||||
//
|
||||
// This grabs outfits from the Library and copies those over to the user's
|
||||
// outfits folder, typically during first-ever login.
|
||||
//--------------------------------------------------------------------
|
||||
class LLLibraryOutfitsFetch : public LLInventoryFetchDescendentsObserver
|
||||
{
|
||||
public:
|
||||
enum ELibraryOutfitFetchStep
|
||||
{
|
||||
LOFS_FOLDER = 0,
|
||||
LOFS_OUTFITS,
|
||||
LOFS_LIBRARY,
|
||||
LOFS_IMPORTED,
|
||||
LOFS_CONTENTS
|
||||
};
|
||||
|
||||
LLLibraryOutfitsFetch(const LLUUID& my_outfits_id);
|
||||
~LLLibraryOutfitsFetch();
|
||||
|
||||
virtual void done();
|
||||
void doneIdle();
|
||||
LLUUID mMyOutfitsID;
|
||||
void importedFolderFetch();
|
||||
protected:
|
||||
void folderDone();
|
||||
void outfitsDone();
|
||||
void libraryDone();
|
||||
void importedFolderDone();
|
||||
void contentsDone();
|
||||
enum ELibraryOutfitFetchStep mCurrFetchStep;
|
||||
uuid_vec_t mLibraryClothingFolders;
|
||||
uuid_vec_t mImportedClothingFolders;
|
||||
bool mOutfitsPopulated;
|
||||
LLUUID mClothingID;
|
||||
LLUUID mLibraryClothingID;
|
||||
LLUUID mImportedClothingID;
|
||||
std::string mImportedClothingName;
|
||||
};
|
||||
|
||||
#endif // LL_AGENTWEARABLESINITIALFETCH_H
|
||||
3138
indra/newview/llappearancemgr.cpp
Normal file
3138
indra/newview/llappearancemgr.cpp
Normal file
File diff suppressed because it is too large
Load Diff
265
indra/newview/llappearancemgr.h
Normal file
265
indra/newview/llappearancemgr.h
Normal file
@@ -0,0 +1,265 @@
|
||||
/**
|
||||
* @file llappearancemgr.h
|
||||
* @brief Manager for initiating appearance changes on the viewer
|
||||
*
|
||||
* $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$
|
||||
*/
|
||||
|
||||
#ifndef LL_LLAPPEARANCEMGR_H
|
||||
#define LL_LLAPPEARANCEMGR_H
|
||||
|
||||
#include "llsingleton.h"
|
||||
|
||||
#include "llagentwearables.h"
|
||||
#include "llcallbacklist.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llviewerinventory.h"
|
||||
|
||||
class LLWearable;
|
||||
class LLWearableHoldingPattern;
|
||||
class LLInventoryCallback;
|
||||
class LLOutfitUnLockTimer;
|
||||
|
||||
class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
|
||||
{
|
||||
LOG_CLASS(LLAppearanceMgr);
|
||||
|
||||
friend class LLSingleton<LLAppearanceMgr>;
|
||||
friend class LLOutfitUnLockTimer;
|
||||
|
||||
public:
|
||||
typedef std::vector<LLInventoryModel::item_array_t> wearables_by_type_t;
|
||||
|
||||
void updateAppearanceFromCOF(bool update_base_outfit_ordering = false);
|
||||
bool needToSaveCOF();
|
||||
void updateCOF(const LLUUID& category, bool append = false);
|
||||
// [RLVa:KB] - Checked: 2010-03-05 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
|
||||
void updateCOF(LLInventoryModel::item_array_t& body_items_new, LLInventoryModel::item_array_t& wear_items_new,
|
||||
LLInventoryModel::item_array_t& obj_items_new, LLInventoryModel::item_array_t& gest_items_new,
|
||||
bool append = false, const LLUUID& idOutfit = LLUUID::null);
|
||||
// [/RLVa:KB]
|
||||
void wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append);
|
||||
void wearInventoryCategoryOnAvatar(LLInventoryCategory* category, bool append);
|
||||
void wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append);
|
||||
void wearOutfitByName(const std::string& name);
|
||||
void changeOutfit(bool proceed, const LLUUID& category, bool append);
|
||||
void replaceCurrentOutfit(const LLUUID& new_outfit);
|
||||
void renameOutfit(const LLUUID& outfit_id);
|
||||
void takeOffOutfit(const LLUUID& cat_id);
|
||||
void addCategoryToCurrentOutfit(const LLUUID& cat_id);
|
||||
S32 findExcessOrDuplicateItems(const LLUUID& cat_id,
|
||||
LLAssetType::EType type,
|
||||
S32 max_items,
|
||||
LLInventoryModel::item_array_t& items_to_kill);
|
||||
void enforceItemRestrictions();
|
||||
|
||||
// Copy all items and the src category itself.
|
||||
void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
|
||||
LLPointer<LLInventoryCallback> cb);
|
||||
|
||||
// Return whether this folder contains minimal contents suitable for making a full outfit.
|
||||
BOOL getCanMakeFolderIntoOutfit(const LLUUID& folder_id);
|
||||
|
||||
// Determine whether a given outfit can be removed.
|
||||
bool getCanRemoveOutfit(const LLUUID& outfit_cat_id);
|
||||
|
||||
// Determine whether we're wearing any of the outfit contents (excluding body parts).
|
||||
static bool getCanRemoveFromCOF(const LLUUID& outfit_cat_id);
|
||||
|
||||
// Determine whether we can add anything (but body parts) from the outfit contents to COF.
|
||||
static bool getCanAddToCOF(const LLUUID& outfit_cat_id);
|
||||
|
||||
// Determine whether we can replace current outfit with the given one.
|
||||
bool getCanReplaceCOF(const LLUUID& outfit_cat_id);
|
||||
|
||||
// Copy all items in a category.
|
||||
void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
|
||||
LLPointer<LLInventoryCallback> cb);
|
||||
|
||||
// Find the Current Outfit folder.
|
||||
const LLUUID getCOF() const;
|
||||
|
||||
// Finds the folder link to the currently worn outfit
|
||||
const LLViewerInventoryItem *getBaseOutfitLink();
|
||||
bool getBaseOutfitName(std::string &name);
|
||||
|
||||
// find the UUID of the currently worn outfit (Base Outfit)
|
||||
const LLUUID getBaseOutfitUUID();
|
||||
|
||||
// Wear/attach an item (from a user's inventory) on the agent
|
||||
bool wearItemOnAvatar(const LLUUID& item_to_wear, bool do_update = true, bool replace = false, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
|
||||
// Update the displayed outfit name in UI.
|
||||
void updatePanelOutfitName(const std::string& name);
|
||||
|
||||
void createBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> link_waiter);
|
||||
|
||||
void updateAgentWearables(LLWearableHoldingPattern* holder, bool append);
|
||||
|
||||
// For debugging - could be moved elsewhere.
|
||||
void dumpCat(const LLUUID& cat_id, const std::string& msg);
|
||||
void dumpItemArray(const LLInventoryModel::item_array_t& items, const std::string& msg);
|
||||
|
||||
// Attachment link management
|
||||
void unregisterAttachment(const LLUUID& item_id);
|
||||
void registerAttachment(const LLUUID& item_id);
|
||||
void setAttachmentInvLinkEnable(bool val);
|
||||
|
||||
// utility function for bulk linking.
|
||||
void linkAll(const LLUUID& category,
|
||||
LLInventoryModel::item_array_t& items,
|
||||
LLPointer<LLInventoryCallback> cb);
|
||||
|
||||
// Add COF link to individual item.
|
||||
void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL);
|
||||
|
||||
// Remove COF entries
|
||||
void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true);
|
||||
void removeCOFLinksOfType(LLWearableType::EType type, bool do_update = true);
|
||||
|
||||
// Add COF link to ensemble folder.
|
||||
void addEnsembleLink(LLInventoryCategory* item, bool do_update = true);
|
||||
|
||||
//has the current outfit changed since it was loaded?
|
||||
bool isOutfitDirty() { return mOutfitIsDirty; }
|
||||
|
||||
// set false if you just loaded the outfit, true otherwise
|
||||
void setOutfitDirty(bool isDirty) { mOutfitIsDirty = isDirty; }
|
||||
|
||||
// manually compare ouftit folder link to COF to see if outfit has changed.
|
||||
// should only be necessary to do on initial login.
|
||||
void updateIsDirty();
|
||||
|
||||
// Called when self avatar is first fully visible.
|
||||
void onFirstFullyVisible();
|
||||
|
||||
// Create initial outfits from library.
|
||||
void autopopulateOutfits();
|
||||
|
||||
// Copy initial gestures from library.
|
||||
void copyLibraryGestures();
|
||||
|
||||
void wearBaseOutfit();
|
||||
|
||||
// Overrides the base outfit with the content from COF
|
||||
// @return false if there is no base outfit
|
||||
bool updateBaseOutfit();
|
||||
|
||||
//Remove clothing or detach an object from the agent (a bodypart cannot be removed)
|
||||
void removeItemFromAvatar(const LLUUID& item_id);
|
||||
|
||||
|
||||
LLUUID makeNewOutfitLinks(const std::string& new_folder_name,bool show_panel = true);
|
||||
|
||||
bool moveWearable(LLViewerInventoryItem* item, bool closer_to_body);
|
||||
|
||||
static void sortItemsByActualDescription(LLInventoryModel::item_array_t& items);
|
||||
|
||||
//Divvy items into arrays by wearable type
|
||||
static void divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type);
|
||||
|
||||
//Check ordering information on wearables stored in links' descriptions and update if it is invalid
|
||||
// COF is processed if cat_id is not specified
|
||||
void updateClothingOrderingInfo(LLUUID cat_id = LLUUID::null, bool update_base_outfit_ordering = false);
|
||||
|
||||
bool isOutfitLocked() { return mOutfitLocked; }
|
||||
|
||||
bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; }
|
||||
|
||||
protected:
|
||||
LLAppearanceMgr();
|
||||
~LLAppearanceMgr();
|
||||
|
||||
private:
|
||||
|
||||
void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type);
|
||||
|
||||
void getDescendentsOfAssetType(const LLUUID& category,
|
||||
LLInventoryModel::item_array_t& items,
|
||||
LLAssetType::EType type,
|
||||
bool follow_folder_links);
|
||||
|
||||
void getUserDescendents(const LLUUID& category,
|
||||
LLInventoryModel::item_array_t& wear_items,
|
||||
LLInventoryModel::item_array_t& obj_items,
|
||||
LLInventoryModel::item_array_t& gest_items,
|
||||
bool follow_folder_links);
|
||||
|
||||
void purgeCategory(const LLUUID& category, bool keep_outfit_links);
|
||||
void purgeBaseOutfitLink(const LLUUID& category);
|
||||
|
||||
static void onOutfitRename(const LLSD& notification, const LLSD& response);
|
||||
|
||||
void setOutfitLocked(bool locked);
|
||||
|
||||
bool mAttachmentInvLinkEnabled;
|
||||
bool mOutfitIsDirty;
|
||||
bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls.
|
||||
|
||||
/**
|
||||
* Lock for blocking operations on outfit until server reply or timeout exceed
|
||||
* to avoid unsynchronized outfit state or performing duplicate operations.
|
||||
*/
|
||||
bool mOutfitLocked;
|
||||
|
||||
std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Item-specific convenience functions
|
||||
public:
|
||||
// Is this in the COF?
|
||||
BOOL getIsInCOF(const LLUUID& obj_id) const;
|
||||
// Is this in the COF and can the user delete it from the COF?
|
||||
BOOL getIsProtectedCOFItem(const LLUUID& obj_id) const;
|
||||
|
||||
/**
|
||||
* Checks if COF contains link to specified object.
|
||||
*/
|
||||
static bool isLinkInCOF(const LLUUID& obj_id);
|
||||
};
|
||||
|
||||
class LLUpdateAppearanceOnDestroy: public LLInventoryCallback
|
||||
{
|
||||
public:
|
||||
LLUpdateAppearanceOnDestroy(bool update_base_outfit_ordering = false);
|
||||
virtual ~LLUpdateAppearanceOnDestroy();
|
||||
/* virtual */ void fire(const LLUUID& inv_item);
|
||||
|
||||
private:
|
||||
U32 mFireCount;
|
||||
bool mUpdateBaseOrder;
|
||||
};
|
||||
|
||||
|
||||
#define SUPPORT_ENSEMBLES 0
|
||||
|
||||
LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id,const std::string& name);
|
||||
|
||||
// Invoke a given callable after category contents are fully fetched.
|
||||
void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb);
|
||||
|
||||
// Wear all items in a uuid vector.
|
||||
void wear_multiple(const uuid_vec_t& ids, bool replace);
|
||||
|
||||
#endif
|
||||
@@ -3583,7 +3583,7 @@ void LLAppViewer::badNetworkHandler()
|
||||
std::string grid_support_msg = "";
|
||||
if (!gHippoGridManager->getCurrentGrid()->getSupportUrl().empty())
|
||||
{
|
||||
grid_support_msg = "\n\nOr visit the gird support page at: \n "
|
||||
grid_support_msg = "\n\nOr visit the grid support page at: \n "
|
||||
+ gHippoGridManager->getCurrentGrid()->getSupportUrl();
|
||||
}
|
||||
std::ostringstream message;
|
||||
@@ -3915,7 +3915,7 @@ void LLAppViewer::idle()
|
||||
return;
|
||||
}
|
||||
|
||||
gViewerWindow->handlePerFrameHover();
|
||||
gViewerWindow->updateUI();
|
||||
|
||||
///////////////////////////////////////
|
||||
// Agent and camera movement
|
||||
@@ -4642,13 +4642,9 @@ void LLAppViewer::handleLoginComplete()
|
||||
{
|
||||
gDebugInfo["MainloopTimeoutState"] = LLAppViewer::instance()->mMainloopTimeout->getState();
|
||||
}
|
||||
writeDebugInfo();
|
||||
|
||||
// [RLVa:KB] - Checked: 2010-09-27 (RLVa-1.1.3b) | Modified: RLVa-1.1.3b
|
||||
if (rlv_handler_t::isEnabled())
|
||||
{
|
||||
gRlvHandler.onLoginComplete();
|
||||
}
|
||||
// [/RLVa:KB]
|
||||
mOnLoginCompleted();
|
||||
|
||||
writeDebugInfo();
|
||||
}
|
||||
|
||||
|
||||
@@ -160,6 +160,11 @@ public:
|
||||
void handleLoginComplete();
|
||||
|
||||
LLAllocator & getAllocator() { return mAlloc; }
|
||||
// On LoginCompleted callback
|
||||
typedef boost::signals2::signal<void (void)> login_completed_signal_t;
|
||||
login_completed_signal_t mOnLoginCompleted;
|
||||
boost::signals2::connection setOnLoginCompletedCallback( const login_completed_signal_t::slot_type& cb ) { return mOnLoginCompleted.connect(cb); }
|
||||
|
||||
void addOnIdleCallback(const boost::function<void()>& cb); // add a callback to fire (once) when idle
|
||||
|
||||
void purgeCache(); // Clear the local cache.
|
||||
|
||||
@@ -34,19 +34,12 @@
|
||||
|
||||
#include "llassetuploadresponders.h"
|
||||
|
||||
// library includes
|
||||
#include "lleconomy.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "llnotifications.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llsdserialize.h"
|
||||
|
||||
// viewer includes
|
||||
#include "llagent.h"
|
||||
#include "llcompilequeue.h"
|
||||
#include "llfloaterbuycurrency.h"
|
||||
#include "llnotify.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llinventorydefines.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "llpanelmaininventory.h"
|
||||
#include "llpermissionsflags.h"
|
||||
@@ -63,6 +56,18 @@
|
||||
#include "llviewermenufile.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "lltexlayer.h"
|
||||
#include "lltrans.h"
|
||||
|
||||
// library includes
|
||||
#include "lldir.h"
|
||||
#include "lleconomy.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llvfs.h"
|
||||
|
||||
#include "statemachine/aifilepicker.h"
|
||||
|
||||
// When uploading multiple files, don't display any of them when uploading more than this number.
|
||||
@@ -70,14 +75,15 @@ static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5;
|
||||
|
||||
void dialog_refresh_all();
|
||||
|
||||
void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type,
|
||||
LLInventoryType::EType inventory_type,
|
||||
const std::string inventory_type_string,
|
||||
const LLUUID& item_folder_id,
|
||||
const std::string& item_name,
|
||||
const std::string& item_description,
|
||||
const LLSD& server_response,
|
||||
S32 upload_price)
|
||||
void on_new_single_inventory_upload_complete(
|
||||
LLAssetType::EType asset_type,
|
||||
LLInventoryType::EType inventory_type,
|
||||
const std::string inventory_type_string,
|
||||
const LLUUID& item_folder_id,
|
||||
const std::string& item_name,
|
||||
const std::string& item_description,
|
||||
const LLSD& server_response,
|
||||
S32 upload_price)
|
||||
{
|
||||
if (upload_price > 0)
|
||||
{
|
||||
@@ -87,7 +93,7 @@ void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type,
|
||||
|
||||
LLSD args;
|
||||
args["AMOUNT"] = llformat("%d", upload_price);
|
||||
LLNotifications::instance().add("UploadPayment", args);
|
||||
LLNotificationsUtil::add("UploadPayment", args);
|
||||
}
|
||||
|
||||
if (item_folder_id.notNull())
|
||||
@@ -115,9 +121,18 @@ void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type,
|
||||
}
|
||||
|
||||
LLPermissions new_perms;
|
||||
new_perms.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
|
||||
new_perms.initMasks(PERM_ALL, PERM_ALL, everyone_perms, group_perms,
|
||||
next_owner_perms);
|
||||
new_perms.init(
|
||||
gAgent.getID(),
|
||||
gAgent.getID(),
|
||||
LLUUID::null,
|
||||
LLUUID::null);
|
||||
|
||||
new_perms.initMasks(
|
||||
PERM_ALL,
|
||||
PERM_ALL,
|
||||
everyone_perms,
|
||||
group_perms,
|
||||
next_owner_perms);
|
||||
|
||||
U32 inventory_item_flags = 0;
|
||||
if (server_response.has("inventory_flags"))
|
||||
@@ -147,17 +162,18 @@ void on_new_single_inventory_upload_complete(LLAssetType::EType asset_type,
|
||||
|
||||
// Show the preview panel for textures and sounds to let
|
||||
// user know that the image (or snapshot) arrived intact.
|
||||
LLInventoryView* view = LLInventoryView::getActiveInventory();
|
||||
if (view)
|
||||
LLInventoryPanel* panel = LLInventoryPanel::getActiveInventoryPanel();
|
||||
if ( panel )
|
||||
{
|
||||
LLFocusableElement* focus = gFocusMgr.getKeyboardFocus();
|
||||
|
||||
view->getPanel()->setSelection(server_response["new_inventory_item"].asUUID(),
|
||||
TAKE_FOCUS_NO);
|
||||
panel->setSelection(
|
||||
server_response["new_inventory_item"].asUUID(),
|
||||
TAKE_FOCUS_NO);
|
||||
if ((LLAssetType::AT_TEXTURE == asset_type || LLAssetType::AT_SOUND == asset_type)
|
||||
/* FIXME: && LLFilePicker::instance().getFileCount() <= FILE_COUNT_DISPLAY_THRESHOLD */)
|
||||
{
|
||||
view->getPanel()->openSelected();
|
||||
panel->openSelected();
|
||||
}
|
||||
|
||||
// restore keyboard focus
|
||||
@@ -190,7 +206,8 @@ LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
|
||||
}
|
||||
}
|
||||
|
||||
LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
|
||||
LLAssetUploadResponder::LLAssetUploadResponder(
|
||||
const LLSD &post_data,
|
||||
const std::string& file_name,
|
||||
LLAssetType::EType asset_type)
|
||||
: LLHTTPClient::Responder(),
|
||||
@@ -221,14 +238,14 @@ void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
|
||||
args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
|
||||
args["REASON"] = "Error in upload request. Please visit "
|
||||
"http://secondlife.com/support for help fixing this problem.";
|
||||
LLNotifications::instance().add("CannotUploadReason", args);
|
||||
LLNotificationsUtil::add("CannotUploadReason", args);
|
||||
break;
|
||||
case 500:
|
||||
default:
|
||||
args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
|
||||
args["REASON"] = "The server is experiencing unexpected "
|
||||
"difficulties.";
|
||||
LLNotifications::instance().add("CannotUploadReason", args);
|
||||
LLNotificationsUtil::add("CannotUploadReason", args);
|
||||
break;
|
||||
}
|
||||
LLUploadDialog::modalUploadFinished();
|
||||
@@ -291,7 +308,7 @@ void LLAssetUploadResponder::uploadFailure(const LLSD& content)
|
||||
LLSD args;
|
||||
args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
|
||||
args["REASON"] = content["message"].asString();
|
||||
LLNotifications::instance().add("CannotUploadReason", args);
|
||||
LLNotificationsUtil::add("CannotUploadReason", args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,17 +316,19 @@ void LLAssetUploadResponder::uploadComplete(const LLSD& content)
|
||||
{
|
||||
}
|
||||
|
||||
LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data,
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type)
|
||||
: LLAssetUploadResponder(post_data, vfile_id, asset_type)
|
||||
LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(
|
||||
const LLSD& post_data,
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type)
|
||||
: LLAssetUploadResponder(post_data, vfile_id, asset_type)
|
||||
{
|
||||
}
|
||||
|
||||
LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data,
|
||||
const std::string& file_name,
|
||||
LLAssetType::EType asset_type)
|
||||
: LLAssetUploadResponder(post_data, file_name, asset_type)
|
||||
LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(
|
||||
const LLSD& post_data,
|
||||
const std::string& file_name,
|
||||
LLAssetType::EType asset_type)
|
||||
: LLAssetUploadResponder(post_data, file_name, asset_type)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -347,17 +366,21 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
|
||||
asset_type == LLAssetType::AT_ANIMATION ||
|
||||
asset_type == LLAssetType::AT_MESH)
|
||||
{
|
||||
expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
|
||||
expected_upload_cost =
|
||||
LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
|
||||
}
|
||||
|
||||
llinfos << "Adding " << content["new_inventory_item"].asUUID() << " "
|
||||
<< content["new_asset"].asUUID() << " to inventory." << llendl;
|
||||
on_new_single_inventory_upload_complete(asset_type, inventory_type,
|
||||
mPostData["asset_type"].asString(),
|
||||
mPostData["folder_id"].asUUID(),
|
||||
mPostData["name"],
|
||||
mPostData["description"],
|
||||
content, expected_upload_cost);
|
||||
on_new_single_inventory_upload_complete(
|
||||
asset_type,
|
||||
inventory_type,
|
||||
mPostData["asset_type"].asString(),
|
||||
mPostData["folder_id"].asUUID(),
|
||||
mPostData["name"],
|
||||
mPostData["description"],
|
||||
content,
|
||||
expected_upload_cost);
|
||||
|
||||
// continue uploading for bulk uploads
|
||||
|
||||
@@ -378,42 +401,54 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
|
||||
// and use them for each next file to be uploaded. Note the requested
|
||||
// perms are not the same as the granted ones found in the given
|
||||
// "content" structure but can still be found in mPostData. -MG
|
||||
U32 everyone_perms = mPostData.has("everyone_mask") ?
|
||||
mPostData.get("everyone_mask").asInteger() :
|
||||
PERM_NONE;
|
||||
U32 everyone_perms =
|
||||
mPostData.has("everyone_mask") ?
|
||||
mPostData.get("everyone_mask").asInteger() :
|
||||
PERM_NONE;
|
||||
|
||||
U32 group_perms = mPostData.has("group_mask") ?
|
||||
mPostData.get("group_mask").asInteger() :
|
||||
PERM_NONE;
|
||||
U32 group_perms =
|
||||
mPostData.has("group_mask") ?
|
||||
mPostData.get("group_mask").asInteger() :
|
||||
PERM_NONE;
|
||||
|
||||
U32 next_owner_perms = mPostData.has("next_owner_mask") ?
|
||||
mPostData.get("next_owner_mask").asInteger() :
|
||||
PERM_NONE;
|
||||
U32 next_owner_perms =
|
||||
mPostData.has("next_owner_mask") ?
|
||||
mPostData.get("next_owner_mask").asInteger() :
|
||||
PERM_NONE;
|
||||
|
||||
std::string display_name = LLStringUtil::null;
|
||||
LLAssetStorage::LLStoreAssetCallback callback = NULL;
|
||||
void *userdata = NULL;
|
||||
upload_new_resource(next_file, asset_name, asset_name, 0,
|
||||
LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
|
||||
next_owner_perms, group_perms, everyone_perms,
|
||||
display_name, callback, expected_upload_cost,
|
||||
userdata);
|
||||
|
||||
upload_new_resource(
|
||||
next_file,
|
||||
asset_name,
|
||||
asset_name,
|
||||
0,
|
||||
LLFolderType::FT_NONE,
|
||||
LLInventoryType::IT_NONE,
|
||||
next_owner_perms,
|
||||
group_perms,
|
||||
everyone_perms,
|
||||
display_name,
|
||||
callback,
|
||||
expected_upload_cost,
|
||||
userdata);
|
||||
}
|
||||
}
|
||||
|
||||
LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data,
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type,
|
||||
LLBakedUploadData * baked_upload_data)
|
||||
: LLAssetUploadResponder(post_data, vfile_id, asset_type),
|
||||
LLBakedUploadData * baked_upload_data) :
|
||||
LLAssetUploadResponder(post_data, vfile_id, asset_type),
|
||||
mBakedUploadData(baked_upload_data)
|
||||
{
|
||||
}
|
||||
|
||||
LLSendTexLayerResponder::~LLSendTexLayerResponder()
|
||||
{
|
||||
// mBakedUploadData is normally deleted by calls to
|
||||
// LLTexLayerSetBuffer::onTextureUploadComplete() below
|
||||
// mBakedUploadData is normally deleted by calls to LLTexLayerSetBuffer::onTextureUploadComplete() below
|
||||
if (mBakedUploadData)
|
||||
{ // ...but delete it in the case where uploadComplete() is never called
|
||||
delete mBakedUploadData;
|
||||
@@ -430,19 +465,16 @@ void LLSendTexLayerResponder::uploadComplete(const LLSD& content)
|
||||
std::string result = content["state"];
|
||||
LLUUID new_id = content["new_asset"];
|
||||
|
||||
llinfos << "LLSendTexLayerResponder::result from capabilities: " << result << llendl;
|
||||
if (result == "complete" && mBakedUploadData != NULL)
|
||||
llinfos << "result: " << result << " new_id: " << new_id << llendl;
|
||||
if (result == "complete"
|
||||
&& mBakedUploadData != NULL)
|
||||
{ // Invoke
|
||||
LLTexLayerSetBuffer::onTextureUploadComplete(new_id,
|
||||
(void*)mBakedUploadData,
|
||||
0, LL_EXSTAT_NONE);
|
||||
LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE);
|
||||
mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
|
||||
}
|
||||
else
|
||||
{ // Invoke the original callback with an error result
|
||||
LLTexLayerSetBuffer::onTextureUploadComplete(new_id,
|
||||
(void*)mBakedUploadData,
|
||||
-1, LL_EXSTAT_NONE);
|
||||
LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
|
||||
mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
|
||||
}
|
||||
}
|
||||
@@ -452,23 +484,23 @@ void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason)
|
||||
llinfos << "status: " << statusNum << " reason: " << reason << llendl;
|
||||
|
||||
// Invoke the original callback with an error result
|
||||
LLTexLayerSetBuffer::onTextureUploadComplete(LLUUID(),
|
||||
(void*)mBakedUploadData,
|
||||
-1, LL_EXSTAT_NONE);
|
||||
LLTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
|
||||
mBakedUploadData = NULL; // deleted in onTextureUploadComplete()
|
||||
}
|
||||
|
||||
LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type)
|
||||
: LLAssetUploadResponder(post_data, vfile_id, asset_type)
|
||||
LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(
|
||||
const LLSD& post_data,
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type)
|
||||
: LLAssetUploadResponder(post_data, vfile_id, asset_type)
|
||||
{
|
||||
}
|
||||
|
||||
LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(const LLSD& post_data,
|
||||
const std::string& file_name,
|
||||
LLAssetType::EType asset_type)
|
||||
: LLAssetUploadResponder(post_data, file_name, asset_type)
|
||||
LLUpdateAgentInventoryResponder::LLUpdateAgentInventoryResponder(
|
||||
const LLSD& post_data,
|
||||
const std::string& file_name,
|
||||
LLAssetType::EType asset_type)
|
||||
: LLAssetUploadResponder(post_data, file_name, asset_type)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -501,8 +533,7 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content)
|
||||
case LLInventoryType::IT_NOTECARD:
|
||||
{
|
||||
// Update the UI with the new asset.
|
||||
LLPreviewNotecard* nc;
|
||||
nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID());
|
||||
LLPreviewNotecard* nc = (LLPreviewNotecard*)LLPreview::find(new_item->getUUID());
|
||||
if (nc)
|
||||
{
|
||||
// *HACK: we have to delete the asset in the VFS so
|
||||
@@ -511,10 +542,9 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content)
|
||||
// the uploader, so this can be optimized away in some
|
||||
// cases. A better design is to have a new uuid if the
|
||||
// script actually changed the asset.
|
||||
if (nc->hasEmbeddedInventory())
|
||||
if(nc->hasEmbeddedInventory())
|
||||
{
|
||||
gVFS->removeFile(content["new_asset"].asUUID(),
|
||||
LLAssetType::AT_NOTECARD);
|
||||
gVFS->removeFile(content["new_asset"].asUUID(), LLAssetType::AT_NOTECARD);
|
||||
}
|
||||
nc->refreshFromInventory();
|
||||
}
|
||||
@@ -538,15 +568,16 @@ void LLUpdateAgentInventoryResponder::uploadComplete(const LLSD& content)
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case LLInventoryType::IT_GESTURE:
|
||||
{
|
||||
// If this gesture is active, then we need to update the in-memory
|
||||
// active map with the new pointer.
|
||||
if (LLGestureMgr::getInstance()->isGestureActive(item_id))
|
||||
{
|
||||
LLUUID asset_id = new_item->getAssetUUID();
|
||||
LLGestureMgr::getInstance()->replaceGesture(item_id, asset_id);
|
||||
gInventory.notifyObservers();
|
||||
// active map with the new pointer.
|
||||
if (LLGestureMgr::instance().isGestureActive(item_id))
|
||||
{
|
||||
LLUUID asset_id = new_item->getAssetUUID();
|
||||
LLGestureMgr::instance().replaceGesture(item_id, asset_id);
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
|
||||
//gesture will have a new asset_id
|
||||
@@ -639,9 +670,7 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
|
||||
// Bytecode save completed
|
||||
if (content["compiled"])
|
||||
{
|
||||
preview->callbackLSLCompileSucceeded(task_id,
|
||||
item_id,
|
||||
mPostData["is_script_running"]);
|
||||
preview->callbackLSLCompileSucceeded(task_id, item_id, mPostData["is_script_running"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -662,27 +691,30 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content)
|
||||
class LLNewAgentInventoryVariablePriceResponder::Impl
|
||||
{
|
||||
public:
|
||||
Impl(const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type,
|
||||
const LLSD& inventory_data)
|
||||
: mVFileID(vfile_id),
|
||||
Impl(
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type,
|
||||
const LLSD& inventory_data) :
|
||||
mVFileID(vfile_id),
|
||||
mAssetType(asset_type),
|
||||
mInventoryData(inventory_data),
|
||||
mFileName("")
|
||||
{
|
||||
if (!gVFS->getExists(vfile_id, asset_type))
|
||||
{
|
||||
llwarns << "LLAssetUploadResponder called with nonexistant "
|
||||
<< "vfile_id " << vfile_id << llendl;
|
||||
llwarns
|
||||
<< "LLAssetUploadResponder called with nonexistant "
|
||||
<< "vfile_id " << vfile_id << llendl;
|
||||
mVFileID.setNull();
|
||||
mAssetType = LLAssetType::AT_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
Impl(const std::string& file_name,
|
||||
LLAssetType::EType asset_type,
|
||||
const LLSD& inventory_data)
|
||||
: mFileName(file_name),
|
||||
Impl(
|
||||
const std::string& file_name,
|
||||
LLAssetType::EType asset_type,
|
||||
const LLSD& inventory_data) :
|
||||
mFileName(file_name),
|
||||
mAssetType(asset_type),
|
||||
mInventoryData(inventory_data)
|
||||
{
|
||||
@@ -741,7 +773,8 @@ public:
|
||||
args["FILE"] = getFilenameOrIDString();
|
||||
args["REASON"] = reason;
|
||||
|
||||
LLNotifications::instance().add("CannotUploadReason", args);
|
||||
|
||||
LLNotificationsUtil::add("CannotUploadReason", args);
|
||||
LLUploadDialog::modalUploadFinished();
|
||||
}
|
||||
|
||||
@@ -776,45 +809,55 @@ public:
|
||||
else if (_MISSING_REQUIRED_PARAMETER == error_identifier)
|
||||
{
|
||||
// Missing parameters
|
||||
if (error.has(_MISSING_PARAMETER))
|
||||
if (error.has(_MISSING_PARAMETER) )
|
||||
{
|
||||
std::string message = "Upload request was missing required parameter '[P]'";
|
||||
LLStringUtil::replaceString(message, "[P]",
|
||||
error[_MISSING_PARAMETER].asString());
|
||||
std::string message =
|
||||
"Upload request was missing required parameter '[P]'";
|
||||
LLStringUtil::replaceString(
|
||||
message,
|
||||
"[P]",
|
||||
error[_MISSING_PARAMETER].asString());
|
||||
|
||||
displayCannotUploadReason(message);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string message = "Upload request was missing a required parameter";
|
||||
std::string message =
|
||||
"Upload request was missing a required parameter";
|
||||
displayCannotUploadReason(message);
|
||||
}
|
||||
}
|
||||
else if (_INVALID_REQUEST_BODY == error_identifier)
|
||||
else if ( _INVALID_REQUEST_BODY == error_identifier )
|
||||
{
|
||||
// Invalid request body, check to see if
|
||||
// a particular parameter was invalid
|
||||
if (error.has(_INVALID_PARAMETER))
|
||||
if ( error.has(_INVALID_PARAMETER) )
|
||||
{
|
||||
std::string message = "Upload parameter '[P]' is invalid.";
|
||||
LLStringUtil::replaceString(message, "[P]",
|
||||
error[_INVALID_PARAMETER].asString());
|
||||
LLStringUtil::replaceString(
|
||||
message,
|
||||
"[P]",
|
||||
error[_INVALID_PARAMETER].asString());
|
||||
|
||||
// See if the server also responds with what resource
|
||||
// is missing.
|
||||
if (error.has(_MISSING_RESOURCE))
|
||||
if ( error.has(_MISSING_RESOURCE) )
|
||||
{
|
||||
message += "\nMissing resource '[R]'.";
|
||||
|
||||
LLStringUtil::replaceString(message, "[R]",
|
||||
error[_MISSING_RESOURCE].asString());
|
||||
LLStringUtil::replaceString(
|
||||
message,
|
||||
"[R]",
|
||||
error[_MISSING_RESOURCE].asString());
|
||||
}
|
||||
else if (error.has(_INVALID_RESOURCE))
|
||||
else if ( error.has(_INVALID_RESOURCE) )
|
||||
{
|
||||
message += "\nInvalid resource '[R]'.";
|
||||
|
||||
LLStringUtil::replaceString(message, "[R]",
|
||||
error[_INVALID_RESOURCE].asString());
|
||||
LLStringUtil::replaceString(
|
||||
message,
|
||||
"[R]",
|
||||
error[_INVALID_RESOURCE].asString());
|
||||
}
|
||||
|
||||
displayCannotUploadReason(message);
|
||||
@@ -837,7 +880,8 @@ public:
|
||||
|
||||
void onTransportError()
|
||||
{
|
||||
displayCannotUploadReason("The server is experiencing unexpected difficulties.");
|
||||
displayCannotUploadReason(
|
||||
"The server is experiencing unexpected difficulties.");
|
||||
}
|
||||
|
||||
void onTransportError(const LLSD& error)
|
||||
@@ -852,47 +896,72 @@ public:
|
||||
// TODO*: Pull the user visible strings from an xml file
|
||||
// to be localized
|
||||
|
||||
if (_SERVER_ERROR_AFTER_CHARGE == error_identifier)
|
||||
if ( _SERVER_ERROR_AFTER_CHARGE == error_identifier )
|
||||
{
|
||||
displayCannotUploadReason("The server is experiencing unexpected difficulties. You may have been charged for the upload.");
|
||||
displayCannotUploadReason(
|
||||
"The server is experiencing unexpected difficulties. You may have been charged for the upload.");
|
||||
}
|
||||
else
|
||||
{
|
||||
displayCannotUploadReason("The server is experiencing unexpected difficulties.");
|
||||
displayCannotUploadReason(
|
||||
"The server is experiencing unexpected difficulties.");
|
||||
}
|
||||
}
|
||||
|
||||
bool uploadConfirmationCallback(const LLSD& notification,
|
||||
const LLSD& response,
|
||||
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder)
|
||||
bool uploadConfirmationCallback(
|
||||
const LLSD& notification,
|
||||
const LLSD& response,
|
||||
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder)
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
std::string confirmation_url = notification["payload"]["confirmation_url"].asString();
|
||||
S32 option;
|
||||
std::string confirmation_url;
|
||||
|
||||
option = LLNotificationsUtil::getSelectedOption(
|
||||
notification,
|
||||
response);
|
||||
|
||||
confirmation_url =
|
||||
notification["payload"]["confirmation_url"].asString();
|
||||
|
||||
// Yay! We are confirming or cancelling our upload
|
||||
if (option == 0)
|
||||
switch(option)
|
||||
{
|
||||
confirmUpload(confirmation_url, responder);
|
||||
case 0:
|
||||
{
|
||||
confirmUpload(confirmation_url, responder);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void confirmUpload(const std::string& confirmation_url,
|
||||
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder)
|
||||
void confirmUpload(
|
||||
const std::string& confirmation_url,
|
||||
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder> responder)
|
||||
{
|
||||
if (getFilename().empty())
|
||||
if ( getFilename().empty() )
|
||||
{
|
||||
// we have no filename, use virtual file ID instead
|
||||
LLHTTPClient::postFile(confirmation_url, getVFileID(),
|
||||
getAssetType(), responder);
|
||||
LLHTTPClient::postFile(
|
||||
confirmation_url,
|
||||
getVFileID(),
|
||||
getAssetType(),
|
||||
responder);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLHTTPClient::postFile(confirmation_url, getFilename(), responder);
|
||||
LLHTTPClient::postFile(
|
||||
confirmation_url,
|
||||
getFilename(),
|
||||
responder);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
std::string mFileName;
|
||||
|
||||
@@ -904,18 +973,26 @@ private:
|
||||
///////////////////////////////////////////////
|
||||
// LLNewAgentInventoryVariablePriceResponder //
|
||||
///////////////////////////////////////////////
|
||||
LLNewAgentInventoryVariablePriceResponder::LLNewAgentInventoryVariablePriceResponder(const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type,
|
||||
const LLSD& inventory_info)
|
||||
LLNewAgentInventoryVariablePriceResponder::LLNewAgentInventoryVariablePriceResponder(
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type,
|
||||
const LLSD& inventory_info)
|
||||
{
|
||||
mImpl = new Impl(vfile_id, asset_type, inventory_info);
|
||||
mImpl = new Impl(
|
||||
vfile_id,
|
||||
asset_type,
|
||||
inventory_info);
|
||||
}
|
||||
|
||||
LLNewAgentInventoryVariablePriceResponder::LLNewAgentInventoryVariablePriceResponder(const std::string& file_name,
|
||||
LLAssetType::EType asset_type,
|
||||
const LLSD& inventory_info)
|
||||
LLNewAgentInventoryVariablePriceResponder::LLNewAgentInventoryVariablePriceResponder(
|
||||
const std::string& file_name,
|
||||
LLAssetType::EType asset_type,
|
||||
const LLSD& inventory_info)
|
||||
{
|
||||
mImpl = new Impl(file_name, asset_type, inventory_info);
|
||||
mImpl = new Impl(
|
||||
file_name,
|
||||
asset_type,
|
||||
inventory_info);
|
||||
}
|
||||
|
||||
LLNewAgentInventoryVariablePriceResponder::~LLNewAgentInventoryVariablePriceResponder()
|
||||
@@ -923,16 +1000,19 @@ LLNewAgentInventoryVariablePriceResponder::~LLNewAgentInventoryVariablePriceResp
|
||||
delete mImpl;
|
||||
}
|
||||
|
||||
void LLNewAgentInventoryVariablePriceResponder::errorWithContent(U32 statusNum,
|
||||
const std::string& reason,
|
||||
const LLSD& content)
|
||||
void LLNewAgentInventoryVariablePriceResponder::errorWithContent(
|
||||
U32 statusNum,
|
||||
const std::string& reason,
|
||||
const LLSD& content)
|
||||
{
|
||||
LL_DEBUGS("Upload") << "LLNewAgentInventoryVariablePrice::error "
|
||||
<< statusNum << " reason: " << reason << LL_ENDL;
|
||||
lldebugs
|
||||
<< "LLNewAgentInventoryVariablePrice::error " << statusNum
|
||||
<< " reason: " << reason << llendl;
|
||||
|
||||
if (content.has("error"))
|
||||
if ( content.has("error") )
|
||||
{
|
||||
static const std::string _ERROR = "error";
|
||||
|
||||
mImpl->onTransportError(content[_ERROR]);
|
||||
}
|
||||
else
|
||||
@@ -972,27 +1052,32 @@ void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content)
|
||||
{
|
||||
// rename the file in the VFS to the actual asset id
|
||||
// llinfos << "Changing uploaded asset UUID to " << content["new_asset"].asUUID() << llendl;
|
||||
gVFS->renameFile(mImpl->getVFileID(), asset_type,
|
||||
content["new_asset"].asUUID(), asset_type);
|
||||
gVFS->renameFile(
|
||||
mImpl->getVFileID(),
|
||||
asset_type,
|
||||
content["new_asset"].asUUID(),
|
||||
asset_type);
|
||||
}
|
||||
|
||||
on_new_single_inventory_upload_complete(asset_type,
|
||||
mImpl->getInventoryType(),
|
||||
mImpl->getInventoryTypeString(),
|
||||
mImpl->getFolderID(),
|
||||
mImpl->getItemName(),
|
||||
mImpl->getItemDescription(),
|
||||
content,
|
||||
content[_UPLOAD_PRICE].asInteger());
|
||||
on_new_single_inventory_upload_complete(
|
||||
asset_type,
|
||||
mImpl->getInventoryType(),
|
||||
mImpl->getInventoryTypeString(),
|
||||
mImpl->getFolderID(),
|
||||
mImpl->getItemName(),
|
||||
mImpl->getItemDescription(),
|
||||
content,
|
||||
content[_UPLOAD_PRICE].asInteger());
|
||||
|
||||
// TODO* Add bulk (serial) uploading or add
|
||||
// a super class of this that does so
|
||||
}
|
||||
else if (_CONFIRM_UPLOAD == state)
|
||||
else if ( _CONFIRM_UPLOAD == state )
|
||||
{
|
||||
showConfirmationDialog(content[_UPLOAD_PRICE].asInteger(),
|
||||
content[_RESOURCE_COST].asInteger(),
|
||||
content[_RSVP].asString());
|
||||
showConfirmationDialog(
|
||||
content[_UPLOAD_PRICE].asInteger(),
|
||||
content[_RESOURCE_COST].asInteger(),
|
||||
content[_RSVP].asString());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1000,14 +1085,16 @@ void LLNewAgentInventoryVariablePriceResponder::result(const LLSD& content)
|
||||
}
|
||||
}
|
||||
|
||||
void LLNewAgentInventoryVariablePriceResponder::onApplicationLevelError(const LLSD& error)
|
||||
void LLNewAgentInventoryVariablePriceResponder::onApplicationLevelError(
|
||||
const LLSD& error)
|
||||
{
|
||||
mImpl->onApplicationLevelError(error);
|
||||
}
|
||||
|
||||
void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(S32 upload_price,
|
||||
S32 resource_cost,
|
||||
const std::string& confirmation_url)
|
||||
void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(
|
||||
S32 upload_price,
|
||||
S32 resource_cost,
|
||||
const std::string& confirmation_url)
|
||||
{
|
||||
if (0 == upload_price)
|
||||
{
|
||||
@@ -1027,8 +1114,9 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(S32 uploa
|
||||
// when using plain ol' 'this', that this object
|
||||
// would be deleted before the callback is triggered
|
||||
// and cause sadness.
|
||||
mImpl->confirmUpload(confirmation_url,
|
||||
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this));
|
||||
mImpl->confirmUpload(
|
||||
confirmation_url,
|
||||
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1052,10 +1140,15 @@ void LLNewAgentInventoryVariablePriceResponder::showConfirmationDialog(S32 uploa
|
||||
// when using plain ol' 'this', that this object
|
||||
// would be deleted before the callback is triggered
|
||||
// and cause sadness.
|
||||
LLNotifications::instance().add("UploadCostConfirmation",
|
||||
substitutions, payload,
|
||||
boost::bind(&LLNewAgentInventoryVariablePriceResponder::Impl::uploadConfirmationCallback,
|
||||
mImpl, _1, _2,
|
||||
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this)));
|
||||
LLNotificationsUtil::add(
|
||||
"UploadCostConfirmation",
|
||||
substitutions,
|
||||
payload,
|
||||
boost::bind(
|
||||
&LLNewAgentInventoryVariablePriceResponder::Impl::uploadConfirmationCallback,
|
||||
mImpl,
|
||||
_1,
|
||||
_2,
|
||||
boost::intrusive_ptr<LLNewAgentInventoryVariablePriceResponder>(this)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,12 +73,14 @@ protected:
|
||||
class LLNewAgentInventoryResponder : public LLAssetUploadResponder
|
||||
{
|
||||
public:
|
||||
LLNewAgentInventoryResponder(const LLSD& post_data,
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type);
|
||||
LLNewAgentInventoryResponder(const LLSD& post_data,
|
||||
const std::string& file_name,
|
||||
LLAssetType::EType asset_type);
|
||||
LLNewAgentInventoryResponder(
|
||||
const LLSD& post_data,
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type);
|
||||
LLNewAgentInventoryResponder(
|
||||
const LLSD& post_data,
|
||||
const std::string& file_name,
|
||||
LLAssetType::EType asset_type);
|
||||
virtual void error(U32 statusNum, const std::string& reason);
|
||||
virtual void uploadComplete(const LLSD& content);
|
||||
virtual void uploadFailure(const LLSD& content);
|
||||
@@ -92,23 +94,28 @@ class LLNewAgentInventoryVariablePriceResponder :
|
||||
public LLHTTPClient::Responder
|
||||
{
|
||||
public:
|
||||
LLNewAgentInventoryVariablePriceResponder(const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type,
|
||||
const LLSD& inventory_info);
|
||||
LLNewAgentInventoryVariablePriceResponder(
|
||||
const LLUUID& vfile_id,
|
||||
LLAssetType::EType asset_type,
|
||||
const LLSD& inventory_info);
|
||||
|
||||
LLNewAgentInventoryVariablePriceResponder(const std::string& file_name,
|
||||
LLAssetType::EType asset_type,
|
||||
const LLSD& inventory_info);
|
||||
LLNewAgentInventoryVariablePriceResponder(
|
||||
const std::string& file_name,
|
||||
LLAssetType::EType asset_type,
|
||||
const LLSD& inventory_info);
|
||||
virtual ~LLNewAgentInventoryVariablePriceResponder();
|
||||
|
||||
void errorWithContent(U32 statusNum,
|
||||
const std::string& reason,
|
||||
const LLSD& content);
|
||||
void errorWithContent(
|
||||
U32 statusNum,
|
||||
const std::string& reason,
|
||||
const LLSD& content);
|
||||
void result(const LLSD& content);
|
||||
|
||||
virtual void onApplicationLevelError(const LLSD& error);
|
||||
virtual void showConfirmationDialog(S32 upload_price,
|
||||
S32 resource_cost,
|
||||
virtual void onApplicationLevelError(
|
||||
const LLSD& error);
|
||||
virtual void showConfirmationDialog(
|
||||
S32 upload_price,
|
||||
S32 resource_cost,
|
||||
const std::string& confirmation_url);
|
||||
|
||||
private:
|
||||
@@ -116,7 +123,7 @@ private:
|
||||
Impl* mImpl;
|
||||
};
|
||||
|
||||
class LLBakedUploadData;
|
||||
struct LLBakedUploadData;
|
||||
class LLSendTexLayerResponder : public LLAssetUploadResponder
|
||||
{
|
||||
LOG_CLASS(LLSendTexLayerResponder);
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
#ifndef LL_LLATTACHMENTSMGR_H
|
||||
#define LL_LLATTACHMENTSMGR_H
|
||||
|
||||
#include "llmemory.h"
|
||||
#include "llsingleton.h"
|
||||
|
||||
class LLViewerInventoryItem;
|
||||
|
||||
|
||||
@@ -131,9 +131,6 @@ void LLAvatarPropertiesProcessor::sendAvatarPropertiesRequest(const LLUUID& avat
|
||||
|
||||
void LLAvatarPropertiesProcessor::sendAvatarPicksRequest(const LLUUID& avatar_id)
|
||||
{
|
||||
std::string name;
|
||||
gCacheName->getFullName(avatar_id, name);
|
||||
llinfos << "Sending avatarpicksrequest for " << avatar_id << " ("<<name<<")" << llendl;
|
||||
sendGenericRequest(avatar_id, APT_PICKS, "avatarpicksrequest");
|
||||
}
|
||||
|
||||
@@ -398,10 +395,6 @@ void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg,
|
||||
msg->getUUID(_PREHASH_AgentData, _PREHASH_AgentID, avatar_picks.agent_id);
|
||||
msg->getUUID(_PREHASH_AgentData, _PREHASH_TargetID, avatar_picks.target_id);
|
||||
|
||||
std::string name;
|
||||
gCacheName->getFullName(avatar_picks.target_id, name);
|
||||
|
||||
llinfos << "Got reply for " << avatar_picks.target_id << ": (" << name << ")" << llendl;
|
||||
S32 block_count = msg->getNumberOfBlocks(_PREHASH_Data);
|
||||
for (int block = 0; block < block_count; ++block)
|
||||
{
|
||||
@@ -411,14 +404,12 @@ void LLAvatarPropertiesProcessor::processAvatarPicksReply(LLMessageSystem* msg,
|
||||
msg->getUUID(_PREHASH_Data, _PREHASH_PickID, pick_id, block);
|
||||
msg->getString(_PREHASH_Data, _PREHASH_PickName, pick_name, block);
|
||||
|
||||
llinfos << "\t" << pick_id << ": " << pick_name << llendl;
|
||||
avatar_picks.picks_list.push_back(std::make_pair(pick_id,pick_name));
|
||||
}
|
||||
LLAvatarPropertiesProcessor* self = getInstance();
|
||||
// Request processed, no longer pending
|
||||
self->removePendingRequest(avatar_picks.target_id, APT_PICKS);
|
||||
self->notifyObservers(avatar_picks.target_id,&avatar_picks,APT_PICKS);
|
||||
//LLPanelAvatar
|
||||
}
|
||||
|
||||
void LLAvatarPropertiesProcessor::processPickInfoReply(LLMessageSystem* msg, void**)
|
||||
|
||||
@@ -65,12 +65,15 @@ void LLBuildNewViewsScheduler::buildNewViews(LLInventoryPanel* panelp, LLInvento
|
||||
objectp->getType(),
|
||||
LLInventoryType::IT_CATEGORY,
|
||||
panelp,
|
||||
panelp->getRootFolder(),
|
||||
objectp->getUUID());
|
||||
|
||||
if (new_listener)
|
||||
{
|
||||
LLFolderViewFolder* folderp = new LLFolderViewFolder(new_listener->getDisplayName(),
|
||||
new_listener->getIcon(),
|
||||
new_listener->getIcon(),
|
||||
NULL,
|
||||
panelp->getRootFolder(),
|
||||
new_listener);
|
||||
|
||||
@@ -86,12 +89,15 @@ void LLBuildNewViewsScheduler::buildNewViews(LLInventoryPanel* panelp, LLInvento
|
||||
item->getActualType(),
|
||||
item->getInventoryType(),
|
||||
panelp,
|
||||
panelp->getRootFolder(),
|
||||
item->getUUID(),
|
||||
item->getFlags());
|
||||
if (new_listener)
|
||||
{
|
||||
itemp = new LLFolderViewItem(new_listener->getDisplayName(),
|
||||
new_listener->getIcon(),
|
||||
NULL,
|
||||
NULL,
|
||||
new_listener->getCreationDate(),
|
||||
panelp->getRootFolder(),
|
||||
new_listener);
|
||||
@@ -102,7 +108,7 @@ void LLBuildNewViewsScheduler::buildNewViews(LLInventoryPanel* panelp, LLInvento
|
||||
|
||||
if (itemp)
|
||||
{
|
||||
itemp->mDelayedDelete = TRUE;
|
||||
//itemp->mDelayedDelete = TRUE;
|
||||
if (parent_folder)
|
||||
{
|
||||
itemp->addToFolder(parent_folder, panelp->getRootFolder());
|
||||
|
||||
@@ -180,6 +180,12 @@ private:
|
||||
bool_func_t mCallable;
|
||||
};
|
||||
|
||||
void doOnIdleRepeating(bool_func_t callable)
|
||||
{
|
||||
OnIdleCallbackRepeating* cb_functor = new OnIdleCallbackRepeating(callable);
|
||||
gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor);
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
|
||||
void test1(void *data)
|
||||
|
||||
@@ -153,8 +153,8 @@ BOOL LLChatBar::postBuild()
|
||||
{
|
||||
mInputEditor->setCallbackUserData(this);
|
||||
mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke);
|
||||
mInputEditor->setFocusLostCallback(&onInputEditorFocusLost, this);
|
||||
mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus, this );
|
||||
mInputEditor->setFocusLostCallback(boost::bind(&LLChatBar::onInputEditorFocusLost));
|
||||
mInputEditor->setFocusReceivedCallback(boost::bind(&LLChatBar::onInputEditorGainFocus));
|
||||
mInputEditor->setCommitOnFocusLost( FALSE );
|
||||
mInputEditor->setRevertOnEsc( FALSE );
|
||||
mInputEditor->setIgnoreTab(TRUE);
|
||||
@@ -623,14 +623,14 @@ void LLChatBar::onInputEditorKeystroke( LLLineEditor* caller, void* userdata )
|
||||
}
|
||||
|
||||
// static
|
||||
void LLChatBar::onInputEditorFocusLost( LLFocusableElement* caller, void* userdata)
|
||||
void LLChatBar::onInputEditorFocusLost()
|
||||
{
|
||||
// stop typing animation
|
||||
gAgent.stopTyping();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLChatBar::onInputEditorGainFocus( LLFocusableElement* caller, void* userdata )
|
||||
void LLChatBar::onInputEditorGainFocus()
|
||||
{
|
||||
LLFloaterChat::setHistoryCursorAndScrollToEnd();
|
||||
}
|
||||
|
||||
@@ -86,8 +86,8 @@ public:
|
||||
|
||||
static void onTabClick( void* userdata );
|
||||
static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
|
||||
static void onInputEditorFocusLost(LLFocusableElement* caller,void* userdata);
|
||||
static void onInputEditorGainFocus(LLFocusableElement* caller,void* userdata);
|
||||
static void onInputEditorFocusLost();
|
||||
static void onInputEditorGainFocus();
|
||||
|
||||
static void onCommitGesture(LLUICtrl* ctrl, void* data);
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ void LLColorSwatchCtrl::draw()
|
||||
if ( mValid )
|
||||
{
|
||||
// Draw the color swatch
|
||||
gl_rect_2d_checkerboard( getScreenRect(), interior );
|
||||
gl_rect_2d_checkerboard( calcScreenRect(), interior );
|
||||
gl_rect_2d(interior, mColor, TRUE);
|
||||
LLColor4 opaque_color = mColor;
|
||||
opaque_color.mV[VALPHA] = 1.f;
|
||||
@@ -239,7 +239,7 @@ void LLColorSwatchCtrl::draw()
|
||||
LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName);
|
||||
if( fallback_image->getComponents() == 4 )
|
||||
{
|
||||
gl_rect_2d_checkerboard( getScreenRect(), interior );
|
||||
gl_rect_2d_checkerboard( calcScreenRect(), interior );
|
||||
}
|
||||
gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), fallback_image);
|
||||
fallback_image->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file lldriverparam.cpp
|
||||
* @brief A visual parameter that drives (controls) other visual parameters.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -36,6 +30,10 @@
|
||||
|
||||
#include "llfasttimer.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llagent.h"
|
||||
#include "llwearable.h"
|
||||
#include "llagentwearables.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLDriverParamInfo
|
||||
@@ -100,12 +98,69 @@ BOOL LLDriverParamInfo::parseXml(LLXmlTreeNode* node)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLDriverParamInfo::toStream(std::ostream &out)
|
||||
{
|
||||
LLViewerVisualParamInfo::toStream(out);
|
||||
out << "driver" << "\t";
|
||||
out << mDrivenInfoList.size() << "\t";
|
||||
for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
|
||||
{
|
||||
LLDrivenEntryInfo driven = *iter;
|
||||
out << driven.mDrivenID << "\t";
|
||||
}
|
||||
|
||||
out << std::endl;
|
||||
|
||||
if(isAgentAvatarValid())
|
||||
{
|
||||
for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
|
||||
{
|
||||
LLDrivenEntryInfo driven = *iter;
|
||||
LLViewerVisualParam *param = (LLViewerVisualParam*)gAgentAvatarp->getVisualParam(driven.mDrivenID);
|
||||
if (param)
|
||||
{
|
||||
param->getInfo()->toStream(out);
|
||||
if (param->getWearableType() != mWearableType)
|
||||
{
|
||||
if(param->getCrossWearable())
|
||||
{
|
||||
out << "cross-wearable" << "\t";
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "ERROR!" << "\t";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
out << "valid" << "\t";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp << " for driver parameter " << getID() << llendl;
|
||||
}
|
||||
out << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLDriverParam
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
LLDriverParam::LLDriverParam(LLVOAvatar *avatarp)
|
||||
: mCurrentDistortionParam( NULL ), mAvatarp(avatarp)
|
||||
LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) :
|
||||
mCurrentDistortionParam( NULL ),
|
||||
mAvatarp(avatarp),
|
||||
mWearablep(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
LLDriverParam::LLDriverParam(LLWearable *wearablep) :
|
||||
mCurrentDistortionParam( NULL ),
|
||||
mAvatarp(NULL),
|
||||
mWearablep(wearablep)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -122,27 +177,48 @@ BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)
|
||||
mID = info->mID;
|
||||
|
||||
setWeight(getDefaultWeight(), FALSE );
|
||||
|
||||
LLDriverParamInfo::entry_info_list_t::iterator iter;
|
||||
mDriven.reserve(getInfo()->mDrivenInfoList.size());
|
||||
for (iter = getInfo()->mDrivenInfoList.begin(); iter != getInfo()->mDrivenInfoList.end(); iter++)
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLDriverParam::setWearable(LLWearable *wearablep)
|
||||
{
|
||||
if (wearablep)
|
||||
{
|
||||
LLDrivenEntryInfo *driven_info = &(*iter);
|
||||
S32 driven_id = driven_info->mDrivenID;
|
||||
LLViewerVisualParam* param = (LLViewerVisualParam*)mAvatarp->getVisualParam( driven_id );
|
||||
if (param)
|
||||
mWearablep = wearablep;
|
||||
mAvatarp = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void LLDriverParam::setAvatar(LLVOAvatar *avatarp)
|
||||
{
|
||||
if (avatarp)
|
||||
{
|
||||
mWearablep = NULL;
|
||||
mAvatarp = avatarp;
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const
|
||||
{
|
||||
LLDriverParam *new_param;
|
||||
if (wearable)
|
||||
{
|
||||
new_param = new LLDriverParam(wearable);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mWearablep)
|
||||
{
|
||||
mDriven.push_back(LLDrivenEntry( param, driven_info ));
|
||||
new_param = new LLDriverParam(mWearablep);
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "<driven> Unable to resolve driven parameter: " << driven_id << llendl;
|
||||
mInfo = NULL;
|
||||
return FALSE;
|
||||
new_param = new LLDriverParam(mAvatarp);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
*new_param = *this;
|
||||
return new_param;
|
||||
}
|
||||
|
||||
#if 0 // obsolete
|
||||
@@ -408,6 +484,82 @@ void LLDriverParam::stopAnimating(BOOL upload_bake)
|
||||
}
|
||||
}
|
||||
|
||||
/*virtual*/
|
||||
BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params)
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
LLDriverParamInfo::entry_info_list_t::iterator iter;
|
||||
for (iter = getInfo()->mDrivenInfoList.begin(); iter != getInfo()->mDrivenInfoList.end(); ++iter)
|
||||
{
|
||||
LLDrivenEntryInfo *driven_info = &(*iter);
|
||||
S32 driven_id = driven_info->mDrivenID;
|
||||
|
||||
// check for already existing links. Do not overwrite.
|
||||
BOOL found = FALSE;
|
||||
for (entry_list_t::iterator driven_iter = mDriven.begin(); driven_iter != mDriven.end() && !found; ++driven_iter)
|
||||
{
|
||||
if (driven_iter->mInfo->mDrivenID == driven_id)
|
||||
{
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
LLViewerVisualParam* param = (LLViewerVisualParam*)mapper(driven_id);
|
||||
bool push = param && (!only_cross_params || param->getCrossWearable());
|
||||
if (push)
|
||||
{
|
||||
mDriven.push_back(LLDrivenEntry( param, driven_info ));
|
||||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void LLDriverParam::resetDrivenParams()
|
||||
{
|
||||
mDriven.clear();
|
||||
mDriven.reserve(getInfo()->mDrivenInfoList.size());
|
||||
}
|
||||
|
||||
void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type)
|
||||
{
|
||||
bool needs_update = (getWearableType()==driven_type);
|
||||
|
||||
// if the driver has a driven entry for the passed-in wearable type, we need to refresh the value
|
||||
for( entry_list_t::iterator iter = mDriven.begin(); iter != mDriven.end(); iter++ )
|
||||
{
|
||||
LLDrivenEntry* driven = &(*iter);
|
||||
if (driven && driven->mParam && driven->mParam->getCrossWearable() && driven->mParam->getWearableType() == driven_type)
|
||||
{
|
||||
needs_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (needs_update)
|
||||
{
|
||||
LLWearableType::EType driver_type = (LLWearableType::EType)getWearableType();
|
||||
|
||||
// If we've gotten here, we've added a new wearable of type "type"
|
||||
// Thus this wearable needs to get updates from the driver wearable.
|
||||
// The call to setVisualParamWeight seems redundant, but is necessary
|
||||
// as the number of driven wearables has changed since the last update. -Nyx
|
||||
LLWearable *wearable = gAgentWearables.getTopWearable(driver_type);
|
||||
if (wearable)
|
||||
{
|
||||
wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// getDrivenWeight()
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -467,7 +619,7 @@ F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight
|
||||
|
||||
void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake)
|
||||
{
|
||||
/*if(isAgentAvatarValid() &&
|
||||
if(isAgentAvatarValid() &&
|
||||
mWearablep &&
|
||||
driven->mParam->getCrossWearable() &&
|
||||
mWearablep->isOnTop())
|
||||
@@ -475,7 +627,7 @@ void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bo
|
||||
// call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values
|
||||
gAgentAvatarp->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
|
||||
}
|
||||
else*/
|
||||
else
|
||||
{
|
||||
driven->mParam->setWeight( driven_weight, upload_bake );
|
||||
}
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file lldriverparam.h
|
||||
* @brief A visual parameter that drives (controls) other visual parameters.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -34,9 +28,11 @@
|
||||
#define LL_LLDRIVERPARAM_H
|
||||
|
||||
#include "llviewervisualparam.h"
|
||||
#include "llwearabletype.h"
|
||||
|
||||
class LLPhysicsMotion;
|
||||
class LLVOAvatar;
|
||||
class LLWearable;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -70,6 +66,8 @@ public:
|
||||
|
||||
/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
|
||||
|
||||
/*virtual*/ void toStream(std::ostream &out);
|
||||
|
||||
protected:
|
||||
typedef std::deque<LLDrivenEntryInfo> entry_info_list_t;
|
||||
entry_info_list_t mDrivenInfoList;
|
||||
@@ -82,6 +80,7 @@ class LLDriverParam : public LLViewerVisualParam
|
||||
friend class LLPhysicsMotion; // physics motion needs to access driven params directly.
|
||||
public:
|
||||
LLDriverParam(LLVOAvatar *avatarp);
|
||||
LLDriverParam(LLWearable *wearablep);
|
||||
~LLDriverParam();
|
||||
|
||||
// Special: These functions are overridden by child classes
|
||||
@@ -89,12 +88,20 @@ public:
|
||||
// This sets mInfo and calls initialization functions
|
||||
BOOL setInfo(LLDriverParamInfo *info);
|
||||
|
||||
void setWearable(LLWearable *wearablep);
|
||||
void setAvatar(LLVOAvatar *avatarp);
|
||||
void updateCrossDrivenParams(LLWearableType::EType driven_type);
|
||||
|
||||
/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
|
||||
|
||||
// LLVisualParam Virtual functions
|
||||
///*virtual*/ BOOL parseData(LLXmlTreeNode* node);
|
||||
/*virtual*/ void apply( ESex sex ) {} // apply is called separately for each driven param.
|
||||
/*virtual*/ void setWeight(F32 weight, BOOL upload_bake);
|
||||
/*virtual*/ void setAnimationTarget( F32 target_value, BOOL upload_bake );
|
||||
/*virtual*/ void stopAnimating(BOOL upload_bake);
|
||||
/*virtual*/ BOOL linkDrivenParams(visual_param_mapper mapper, BOOL only_cross_params);
|
||||
/*virtual*/ void resetDrivenParams();
|
||||
|
||||
// LLViewerVisualParam Virtual functions
|
||||
/*virtual*/ F32 getTotalDistortion();
|
||||
@@ -115,6 +122,7 @@ protected:
|
||||
LLViewerVisualParam* mCurrentDistortionParam;
|
||||
// Backlink only; don't make this an LLPointer.
|
||||
LLVOAvatar* mAvatarp;
|
||||
LLWearable* mWearablep;
|
||||
};
|
||||
|
||||
#endif // LL_LLDRIVERPARAM_H
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llflexibleobject.cpp
|
||||
* @brief Flexible object implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2006-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2006&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
|
||||
@@ -267,12 +267,13 @@ BOOL LLFloaterAnimPreview::postBuild()
|
||||
{
|
||||
mPlayButton = new LLButton(std::string("play_btn"), LLRect(0,0,0,0));
|
||||
}
|
||||
mPlayButton->setClickedCallback(onBtnPlay);
|
||||
mPlayButton->setCallbackUserData(this);
|
||||
mPlayButton->setClickedCallback(boost::bind(&LLFloaterAnimPreview::onBtnPlay,this));
|
||||
|
||||
mPlayButton->setImages(std::string("button_anim_play.tga"),
|
||||
std::string("button_anim_play_selected.tga"));
|
||||
mPlayButton->setDisabledImages(LLStringUtil::null,LLStringUtil::null);
|
||||
|
||||
mPlayButton->setImageDisabled(NULL);
|
||||
mPlayButton->setImageDisabledSelected(NULL);
|
||||
|
||||
mPlayButton->setScaleImage(TRUE);
|
||||
|
||||
@@ -281,12 +282,13 @@ BOOL LLFloaterAnimPreview::postBuild()
|
||||
{
|
||||
mStopButton = new LLButton(std::string("stop_btn"), LLRect(0,0,0,0));
|
||||
}
|
||||
mStopButton->setClickedCallback(onBtnStop);
|
||||
mStopButton->setCallbackUserData(this);
|
||||
mStopButton->setClickedCallback(boost::bind(&LLFloaterAnimPreview::onBtnStop, this));
|
||||
|
||||
mStopButton->setImages(std::string("button_anim_stop.tga"),
|
||||
std::string("button_anim_stop_selected.tga"));
|
||||
mStopButton->setDisabledImages(LLStringUtil::null,LLStringUtil::null);
|
||||
|
||||
mStopButton->setImageDisabled(NULL);
|
||||
mStopButton->setImageDisabledSelected(NULL);
|
||||
|
||||
mStopButton->setScaleImage(TRUE);
|
||||
|
||||
|
||||
@@ -236,63 +236,35 @@ LLAvatarListEntry::ACTIVITY_TYPE LLAvatarListEntry::getActivity()
|
||||
return mActivityType;
|
||||
}
|
||||
|
||||
LLFloaterAvatarList* LLFloaterAvatarList::sInstance = NULL;
|
||||
|
||||
LLFloaterAvatarList::LLFloaterAvatarList() : LLFloater(std::string("radar"))
|
||||
{
|
||||
llassert_always(sInstance == NULL);
|
||||
sInstance = this;
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_radar.xml");
|
||||
mUpdateRate = gSavedSettings.getU32("RadarUpdateRate") * 3 + 3;
|
||||
}
|
||||
|
||||
LLFloaterAvatarList::~LLFloaterAvatarList()
|
||||
{
|
||||
gIdleCallbacks.deleteFunction(LLFloaterAvatarList::callbackIdle);
|
||||
sInstance = NULL;
|
||||
}
|
||||
//static
|
||||
void LLFloaterAvatarList::createInstance(bool visible)
|
||||
{
|
||||
sInstance = new LLFloaterAvatarList();
|
||||
LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_radar.xml");
|
||||
if(!visible)
|
||||
{
|
||||
sInstance->setVisible(FALSE);
|
||||
gSavedSettings.setBOOL("ShowRadar", FALSE);
|
||||
}
|
||||
if(gHippoGridManager->getConnectedGrid()->isSecondLife()){
|
||||
LLScrollListCtrl* list = sInstance->getChild<LLScrollListCtrl>("avatar_list");
|
||||
list->getColumn(1)->setWidth(0);
|
||||
list->getColumn(6)->setWidth(0);
|
||||
list->getColumn(6)->mDynamicWidth = FALSE;
|
||||
list->getColumn(6)->mRelWidth = 0;
|
||||
list->getColumn(1)->mDynamicWidth = TRUE;
|
||||
list->getColumn(1)->mRelWidth = -1;
|
||||
list->updateLayout();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFloaterAvatarList::toggle(void*)
|
||||
{
|
||||
if (sInstance)
|
||||
{
|
||||
if (sInstance->getVisible()
|
||||
// [RLVa:KB]
|
||||
|| gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)
|
||||
if(gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
|
||||
{
|
||||
if(instanceExists())
|
||||
getInstance()->close();
|
||||
}
|
||||
else
|
||||
// [/RLVa:KB]
|
||||
)
|
||||
|
||||
{
|
||||
sInstance->close(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
sInstance->open();
|
||||
}
|
||||
if(!instanceExists() || !getInstance()->getVisible())
|
||||
{
|
||||
showInstance();
|
||||
}
|
||||
else
|
||||
{
|
||||
showInstance();
|
||||
getInstance()->close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -303,17 +275,7 @@ void LLFloaterAvatarList::showInstance()
|
||||
if(gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
|
||||
return;
|
||||
// [/RLVa:KB]
|
||||
if (sInstance)
|
||||
{
|
||||
if (!sInstance->getVisible())
|
||||
{
|
||||
sInstance->open();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
createInstance(true);
|
||||
}
|
||||
getInstance()->open();
|
||||
}
|
||||
|
||||
void LLFloaterAvatarList::draw()
|
||||
@@ -324,12 +286,11 @@ void LLFloaterAvatarList::draw()
|
||||
void LLFloaterAvatarList::onOpen()
|
||||
{
|
||||
gSavedSettings.setBOOL("ShowRadar", TRUE);
|
||||
sInstance->setVisible(TRUE);
|
||||
}
|
||||
|
||||
void LLFloaterAvatarList::onClose(bool app_quitting)
|
||||
{
|
||||
sInstance->setVisible(FALSE);
|
||||
setVisible(FALSE);
|
||||
if (!app_quitting)
|
||||
{
|
||||
gSavedSettings.setBOOL("ShowRadar", FALSE);
|
||||
@@ -387,12 +348,23 @@ BOOL LLFloaterAvatarList::postBuild()
|
||||
|
||||
gIdleCallbacks.addFunction(LLFloaterAvatarList::callbackIdle);
|
||||
|
||||
if(gHippoGridManager->getConnectedGrid()->isSecondLife()){
|
||||
LLScrollListCtrl* list = sInstance->getChild<LLScrollListCtrl>("avatar_list");
|
||||
list->getColumn(1)->setWidth(0);
|
||||
list->getColumn(6)->setWidth(0);
|
||||
list->getColumn(6)->mDynamicWidth = FALSE;
|
||||
list->getColumn(6)->mRelWidth = 0;
|
||||
list->getColumn(1)->mDynamicWidth = TRUE;
|
||||
list->getColumn(1)->mRelWidth = -1;
|
||||
list->updateLayout();
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void updateParticleActivity(LLDrawable *drawablep)
|
||||
{
|
||||
if (LLFloaterAvatarList::getInstance())
|
||||
if (LLFloaterAvatarList::instanceExists())
|
||||
{
|
||||
LLViewerObject *vobj = drawablep->getVObj();
|
||||
if (vobj && vobj->isParticleSource())
|
||||
@@ -409,10 +381,6 @@ void updateParticleActivity(LLDrawable *drawablep)
|
||||
|
||||
void LLFloaterAvatarList::updateAvatarList()
|
||||
{
|
||||
if (sInstance != this) return;
|
||||
|
||||
//if(LLStartUp::getStartupState() < STATE_STARTED)return;
|
||||
|
||||
//llinfos << "radar refresh: updating map" << llendl;
|
||||
|
||||
// Check whether updates are enabled
|
||||
@@ -672,7 +640,7 @@ void LLFloaterAvatarList::expireAvatarList()
|
||||
void LLFloaterAvatarList::refreshAvatarList()
|
||||
{
|
||||
// Don't update list when interface is hidden
|
||||
if (!sInstance->getVisible()) return;
|
||||
if (!getVisible()) return;
|
||||
|
||||
// We rebuild the list fully each time it's refreshed
|
||||
// The assumption is that it's faster to refill it and sort than
|
||||
@@ -1545,15 +1513,13 @@ void LLFloaterAvatarList::callbackFreeze(const LLSD& notification, const LLSD& r
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
LLFloaterAvatarList *self = LLFloaterAvatarList::sInstance;
|
||||
|
||||
if (option == 0)
|
||||
{
|
||||
self->doCommand(cmd_freeze);
|
||||
getInstance()->doCommand( cmd_freeze );
|
||||
}
|
||||
else if (option == 1)
|
||||
{
|
||||
self->doCommand(cmd_unfreeze);
|
||||
getInstance()->doCommand( cmd_unfreeze );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1562,15 +1528,13 @@ void LLFloaterAvatarList::callbackEject(const LLSD& notification, const LLSD& re
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
LLFloaterAvatarList *self = LLFloaterAvatarList::sInstance;
|
||||
|
||||
if (option == 0)
|
||||
{
|
||||
self->doCommand(cmd_eject);
|
||||
getInstance()->doCommand( cmd_eject );
|
||||
}
|
||||
else if (option == 1)
|
||||
{
|
||||
self->doCommand(cmd_ban);
|
||||
getInstance()->doCommand( cmd_ban );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1579,22 +1543,21 @@ void LLFloaterAvatarList::callbackEjectFromEstate(const LLSD& notification, cons
|
||||
{
|
||||
S32 option = LLNotification::getSelectedOption(notification, response);
|
||||
|
||||
LLFloaterAvatarList *self = LLFloaterAvatarList::sInstance;
|
||||
|
||||
if (option == 0)
|
||||
{
|
||||
self->doCommand(cmd_estate_eject);
|
||||
getInstance()->doCommand( cmd_estate_eject );
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFloaterAvatarList::callbackIdle(void *userdata) {
|
||||
if (LLFloaterAvatarList::sInstance != NULL)
|
||||
void LLFloaterAvatarList::callbackIdle(void *userdata)
|
||||
{
|
||||
if (instanceExists())
|
||||
{
|
||||
// Do not update at every frame: this would be insane !
|
||||
if (gFrameCount % LLFloaterAvatarList::sInstance->mUpdateRate == 0)
|
||||
if (gFrameCount % getInstance()->mUpdateRate == 0)
|
||||
{
|
||||
LLFloaterAvatarList::sInstance->updateAvatarList();
|
||||
getInstance()->updateAvatarList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,12 +159,13 @@ private:
|
||||
* Since I'm very new to C++ any suggestions on coding, style, etc are very
|
||||
* welcome.
|
||||
*/
|
||||
class LLFloaterAvatarList : public LLFloater
|
||||
class LLFloaterAvatarList : public LLFloater, public LLSingleton<LLFloaterAvatarList>
|
||||
{
|
||||
/**
|
||||
* @brief Creates and initializes the LLFloaterAvatarList
|
||||
* Here the interface is created, and callbacks are initialized.
|
||||
*/
|
||||
friend class LLSingleton<LLFloaterAvatarList>;
|
||||
private:
|
||||
LLFloaterAvatarList();
|
||||
public:
|
||||
@@ -211,11 +212,6 @@ public:
|
||||
static void sound_trigger_hook(LLMessageSystem* msg,void **);
|
||||
static void sendKeys();
|
||||
|
||||
private:
|
||||
static LLFloaterAvatarList* sInstance;
|
||||
|
||||
public:
|
||||
static LLFloaterAvatarList* getInstance() { return sInstance; }
|
||||
private:
|
||||
// when a line editor loses keyboard focus, it is committed.
|
||||
// commit callbacks are named onCommitWidgetName by convention.
|
||||
|
||||
@@ -140,7 +140,7 @@ BOOL LLFloaterAvatarPicker::postBuild()
|
||||
inventory_panel->setFollowsAll();
|
||||
inventory_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
inventory_panel->openDefaultFolderForType(LLAssetType::AT_CALLINGCARD);
|
||||
inventory_panel->setSelectCallback(LLFloaterAvatarPicker::onCallingCardSelectionChange, this);
|
||||
inventory_panel->setSelectCallback(boost::bind(&LLFloaterAvatarPicker::onCallingCardSelectionChange, _1, _2, (void*)this));
|
||||
|
||||
childSetTabChangeCallback("ResidentChooserTabs", "SearchPanel", onTabChanged, this);
|
||||
childSetTabChangeCallback("ResidentChooserTabs", "CallingCardsPanel", onTabChanged, this);
|
||||
|
||||
@@ -224,20 +224,17 @@ LLFloaterColorPicker::
|
||||
postBuild()
|
||||
{
|
||||
mCancelBtn = getChild<LLButton>( "cancel_btn" );
|
||||
mCancelBtn->setClickedCallback ( onClickCancel );
|
||||
mCancelBtn->setCallbackUserData ( this );
|
||||
mCancelBtn->setClickedCallback ( boost::bind(&LLFloaterColorPicker::onClickCancel,this) );
|
||||
|
||||
mSelectBtn = getChild<LLButton>( "select_btn");
|
||||
mSelectBtn->setClickedCallback ( onClickSelect );
|
||||
mSelectBtn->setCallbackUserData ( this );
|
||||
mSelectBtn->setClickedCallback ( boost::bind(&LLFloaterColorPicker::onClickSelect,this) );
|
||||
mSelectBtn->setFocus ( TRUE );
|
||||
|
||||
mPipetteBtn = getChild<LLButton>("color_pipette" );
|
||||
|
||||
mPipetteBtn->setImages(std::string("eye_button_inactive.tga"), std::string("eye_button_active.tga"));
|
||||
|
||||
mPipetteBtn->setClickedCallback( onClickPipette );
|
||||
mPipetteBtn->setCallbackUserData ( this );
|
||||
mPipetteBtn->setClickedCallback( boost::bind(&LLFloaterColorPicker::onClickPipette,this) );
|
||||
|
||||
mApplyImmediateCheck = getChild<LLCheckBoxCtrl>("apply_immediate");
|
||||
mApplyImmediateCheck->set(gSavedSettings.getBOOL("ApplyColorImmediately"));
|
||||
@@ -645,6 +642,12 @@ void LLFloaterColorPicker::draw()
|
||||
startX + mLumMarkerSize, startY + mLumMarkerSize,
|
||||
LLColor4 ( 0.0f, 0.0f, 0.0f, 1.0f ), TRUE );
|
||||
|
||||
// draw a white marker inside the black marker to be visible with dark or bright ui.
|
||||
gl_triangle_2d ( startX+2, startY,
|
||||
startX + mLumMarkerSize - 1, startY - mLumMarkerSize + 2,
|
||||
startX + mLumMarkerSize - 1, startY + mLumMarkerSize - 2,
|
||||
LLColor4 ( 1.0f, 1.0f, 1.0f, 1.0f ), TRUE );
|
||||
|
||||
// draw luminance slider outline
|
||||
gl_rect_2d ( mLumRegionLeft,
|
||||
mLumRegionTop - mLumRegionHeight + 1,
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llappearancemgr.h"
|
||||
#include "llimagejpeg.h"
|
||||
#include "llfloatercustomize.h"
|
||||
#include "llfontgl.h"
|
||||
@@ -420,8 +421,12 @@ enum ESubpart {
|
||||
|
||||
struct LLSubpart
|
||||
{
|
||||
LLSubpart() : mSex( SEX_BOTH ), mVisualHint(true) {}
|
||||
|
||||
LLSubpart(const char* pJoint, const char* pGroup, const LLVector3d &target_offs, const LLVector3d &cam_offs, const ESex sex=SEX_BOTH, bool visual_hint=true )
|
||||
: mSex( sex ), mVisualHint(visual_hint), mTargetJoint(pJoint), mEditGroup(pGroup), mTargetOffset(target_offs), mCameraOffset(cam_offs)
|
||||
{}
|
||||
LLSubpart(const char* pJoint, const char* pGroup, const LLVector3d &target_offs, const LLVector3d &cam_offs, bool visual_hint)
|
||||
: mSex( SEX_BOTH ), mVisualHint(visual_hint), mTargetJoint(pJoint), mEditGroup(pGroup), mTargetOffset(target_offs), mCameraOffset(cam_offs)
|
||||
{}
|
||||
std::string mButtonName;
|
||||
std::string mTargetJoint;
|
||||
std::string mEditGroup;
|
||||
@@ -740,14 +745,11 @@ bool LLPanelEditWearable::onSelectAutoWearOption(const LLSD& notification, const
|
||||
|
||||
bool LLPanelEditWearable::textureIsInvisible(ETextureIndex te)
|
||||
{
|
||||
if (gAgentWearables.getWearable(mType, 0)) // TODO: MULTI-WEARABLE
|
||||
const LLWearable* wearable = gAgentWearables.getWearable(mType, 0); // TODO: MULTI-WEARABLE
|
||||
if(wearable)
|
||||
{
|
||||
LLVOAvatar *avatar = gAgentAvatarp;
|
||||
if (avatar)
|
||||
{
|
||||
const LLTextureEntry* current_te = avatar->getTE(te);
|
||||
return (current_te && current_te->getID() == IMG_INVISIBLE);
|
||||
}
|
||||
const LLLocalTextureObject* lto = wearable->getLocalTextureObject(te);
|
||||
return (lto && lto->getID() == IMG_INVISIBLE);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -764,8 +766,7 @@ void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, void* userdata)
|
||||
{
|
||||
LLPanelEditWearable* self = (LLPanelEditWearable*) userdata;
|
||||
LLCheckBoxCtrl* checkbox_ctrl = (LLCheckBoxCtrl*) ctrl;
|
||||
LLVOAvatar *avatar = gAgentAvatarp;
|
||||
if (!avatar)
|
||||
if (!gAgentAvatarp)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -775,14 +776,24 @@ void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, void* userdata)
|
||||
bool new_invis_state = checkbox_ctrl->get();
|
||||
if (new_invis_state)
|
||||
{
|
||||
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(IMG_INVISIBLE);
|
||||
const LLTextureEntry* current_te = avatar->getTE(te);
|
||||
if (current_te)
|
||||
|
||||
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(IMG_INVISIBLE);
|
||||
|
||||
LLWearable* wearable = gAgentWearables.getWearable(self->mType,0); // TODO: MULTI-WEARABLE
|
||||
const LLLocalTextureObject* lto = wearable ? wearable->getLocalTextureObject(te) : NULL;
|
||||
|
||||
if(lto)
|
||||
{
|
||||
self->mPreviousTextureList[(S32)te] = current_te->getID();
|
||||
self->mPreviousTextureList[(S32)te] = lto->getID();
|
||||
}
|
||||
avatar->setLocTexTE(te, image, TRUE);
|
||||
avatar->wearableUpdated(self->mType, FALSE);
|
||||
if(wearable)
|
||||
{
|
||||
LLLocalTextureObject new_lto(image, IMG_INVISIBLE);
|
||||
wearable->setLocalTextureObject(te, new_lto);
|
||||
wearable->writeToAvatar();
|
||||
gAgentAvatarp->wearableUpdated(self->mType, FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -794,9 +805,15 @@ void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, void* userdata)
|
||||
}
|
||||
if (prev_id.notNull())
|
||||
{
|
||||
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(prev_id);
|
||||
avatar->setLocTexTE(te, image, TRUE);
|
||||
avatar->wearableUpdated(self->mType, FALSE);
|
||||
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(prev_id);
|
||||
LLWearable* wearable = gAgentWearables.getWearable(self->mType,0); // TODO: MULTI-WEARABLE
|
||||
if(wearable)
|
||||
{
|
||||
LLLocalTextureObject new_lto(image, prev_id);
|
||||
wearable->setLocalTextureObject(te, new_lto);
|
||||
wearable->writeToAvatar();
|
||||
gAgentAvatarp->wearableUpdated(self->mType, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -814,23 +831,26 @@ void LLPanelEditWearable::onColorCommit( LLUICtrl* ctrl, void* userdata )
|
||||
LLPanelEditWearable* self = (LLPanelEditWearable*) userdata;
|
||||
LLColorSwatchCtrl* color_ctrl = (LLColorSwatchCtrl*) ctrl;
|
||||
|
||||
LLVOAvatar* avatar = gAgentAvatarp;
|
||||
if( self && color_ctrl && avatar )
|
||||
if( self && color_ctrl && gAgentAvatarp )
|
||||
{
|
||||
std::map<std::string, S32>::const_iterator cl_itr = self->mColorList.find(ctrl->getName());
|
||||
if(cl_itr != self->mColorList.end())
|
||||
{
|
||||
ETextureIndex te = (ETextureIndex)cl_itr->second;
|
||||
|
||||
LLColor4 old_color = avatar->getClothesColor( te );
|
||||
LLWearable* wearable = gAgentWearables.getWearable(self->mType, 0); // TODO: MULTI-WEARABLE
|
||||
if(!wearable)
|
||||
return;
|
||||
|
||||
LLColor4 old_color = wearable->getClothesColor( te );
|
||||
const LLColor4& new_color = color_ctrl->get();
|
||||
if( old_color != new_color )
|
||||
{
|
||||
// Set the new version
|
||||
avatar->setClothesColor( te, new_color, TRUE );
|
||||
|
||||
wearable->setClothesColor(te, new_color, TRUE);
|
||||
wearable->writeToAvatar();
|
||||
gAgentAvatarp->wearableUpdated(self->mType, FALSE);
|
||||
LLVisualParamHint::requestHintUpdates();
|
||||
avatar->wearableUpdated(self->mType, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -852,10 +872,15 @@ void LLPanelEditWearable::initPreviousTextureListEntry(ETextureIndex te)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const LLTextureEntry* current_te = avatar->getTE(te);
|
||||
if (current_te)
|
||||
|
||||
LLWearable* wearable = gAgentWearables.getWearable(mType, 0); // TODO: MULTI-WEARABLE
|
||||
if(!wearable)
|
||||
return;
|
||||
|
||||
const LLLocalTextureObject* lto = wearable->getLocalTextureObject(te);
|
||||
if (lto)
|
||||
{
|
||||
mPreviousTextureList[te] = current_te->getID();
|
||||
mPreviousTextureList[te] = lto->getID();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -879,10 +904,10 @@ void LLPanelEditWearable::addTextureDropTarget( ETextureIndex te, const std::str
|
||||
LLWearable* wearable = gAgentWearables.getWearable(mType, 0); // TODO: MULTI-WEARABLE
|
||||
if (wearable && mType == LLWearableType::WT_ALPHA)
|
||||
{
|
||||
const LLTextureEntry* current_te = avatar->getTE(te);
|
||||
if (current_te)
|
||||
const LLLocalTextureObject* lto = wearable->getLocalTextureObject(te);
|
||||
if (lto)
|
||||
{
|
||||
mPreviousTextureList[te] = current_te->getID();
|
||||
mPreviousTextureList[te] = lto->getID();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -894,22 +919,25 @@ void LLPanelEditWearable::onTextureCommit( LLUICtrl* ctrl, void* userdata )
|
||||
LLPanelEditWearable* self = (LLPanelEditWearable*) userdata;
|
||||
LLTextureCtrl* texture_ctrl = (LLTextureCtrl*) ctrl;
|
||||
|
||||
LLVOAvatar* avatar = gAgentAvatarp;
|
||||
if( avatar )
|
||||
if( gAgentAvatarp )
|
||||
{
|
||||
ETextureIndex te = (ETextureIndex)(self->mTextureList[ctrl->getName()]);
|
||||
|
||||
// Set the new version
|
||||
LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( texture_ctrl->getImageAssetID() );
|
||||
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( texture_ctrl->getImageAssetID() );
|
||||
if (image->getID().isNull())
|
||||
{
|
||||
image = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
|
||||
}
|
||||
self->mTextureList[ctrl->getName()] = te;
|
||||
if (gAgentWearables.getWearable(self->mType, 0)) // TODO: MULTI-WEARABLE
|
||||
|
||||
LLWearable* wearable = gAgentWearables.getWearable(self->mType, 0); // TODO: MULTI-WEARABLE
|
||||
if (wearable)
|
||||
{
|
||||
avatar->setLocTexTE(te, image, TRUE);
|
||||
avatar->wearableUpdated(self->mType, FALSE);
|
||||
LLLocalTextureObject lto(image, texture_ctrl->getImageAssetID());
|
||||
wearable->setLocalTextureObject(te, lto);
|
||||
wearable->writeToAvatar();
|
||||
gAgentAvatarp->wearableUpdated(self->mType, FALSE);
|
||||
}
|
||||
if (self->mType == LLWearableType::WT_ALPHA && image->getID() != IMG_INVISIBLE)
|
||||
{
|
||||
@@ -1068,13 +1096,14 @@ void LLPanelEditWearable::draw()
|
||||
childSetVisible(name, is_copyable && is_modifiable && is_complete );
|
||||
if (texture_ctrl)
|
||||
{
|
||||
const LLTextureEntry* te = avatar->getTE(te_index);
|
||||
|
||||
const LLLocalTextureObject* lto = wearable->getLocalTextureObject(te_index);
|
||||
|
||||
LLUUID new_id;
|
||||
|
||||
if( te && (te->getID() != IMG_DEFAULT_AVATAR) )
|
||||
if( lto && (lto->getID() != IMG_DEFAULT_AVATAR) )
|
||||
{
|
||||
new_id = te->getID();
|
||||
new_id = lto->getID();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1093,17 +1122,22 @@ void LLPanelEditWearable::draw()
|
||||
}
|
||||
}
|
||||
|
||||
for( std::map<std::string, S32>::iterator iter = mColorList.begin();
|
||||
iter != mColorList.end(); ++iter )
|
||||
LLWearable* wearable = gAgentWearables.getWearable(mType, 0); // TODO: MULTI-WEARABLE
|
||||
|
||||
if(wearable)
|
||||
{
|
||||
std::string name = iter->first;
|
||||
S32 te_index = iter->second;
|
||||
childSetVisible(name, is_modifiable && is_complete );
|
||||
childSetEnabled(name, is_modifiable && is_complete );
|
||||
LLColorSwatchCtrl* ctrl = getChild<LLColorSwatchCtrl>(name);
|
||||
if (ctrl)
|
||||
for( std::map<std::string, S32>::iterator iter = mColorList.begin();
|
||||
iter != mColorList.end(); ++iter )
|
||||
{
|
||||
ctrl->set(avatar->getClothesColor( (ETextureIndex)te_index ) );
|
||||
std::string name = iter->first;
|
||||
S32 te_index = iter->second;
|
||||
childSetVisible(name, is_modifiable && is_complete );
|
||||
childSetEnabled(name, is_modifiable && is_complete );
|
||||
LLColorSwatchCtrl* ctrl = getChild<LLColorSwatchCtrl>(name);
|
||||
if (ctrl)
|
||||
{
|
||||
ctrl->set( wearable->getClothesColor(te_index ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1231,19 +1265,29 @@ void LLPanelEditWearable::onCommitSexChange( LLUICtrl*, void* userdata )
|
||||
return;
|
||||
}
|
||||
|
||||
LLWearable* wearable = gAgentWearables.getWearable(self->mType,0); // TODO: MULTI-WEARABLE
|
||||
if(!wearable)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ESex new_sex = gSavedSettings.getU32("AvatarSex") ? SEX_MALE : SEX_FEMALE;
|
||||
|
||||
LLViewerVisualParam* param = (LLViewerVisualParam*)avatar->getVisualParam( "male" );
|
||||
LLVisualParam* param = avatar->getVisualParam( "male" );
|
||||
if( !param )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
param->setWeight( (new_sex == SEX_MALE), TRUE );
|
||||
wearable->setVisualParamWeight(param->getID(), (new_sex == SEX_MALE), TRUE);
|
||||
wearable->writeToAvatar();
|
||||
avatar->updateVisualParams();
|
||||
|
||||
/*param->setWeight( (new_sex == SEX_MALE), TRUE );
|
||||
|
||||
avatar->updateSexDependentLayerSets( TRUE );
|
||||
|
||||
avatar->updateVisualParams();
|
||||
avatar->updateVisualParams();*/
|
||||
|
||||
gFloaterCustomize->clearScrollingPanelList();
|
||||
|
||||
@@ -1375,15 +1419,15 @@ LLScrollingPanelParam::LLScrollingPanelParam( const std::string& name,
|
||||
childSetValue("min param text", min_name);
|
||||
childSetValue("max param text", max_name);
|
||||
mLess = getChild<LLButton>("less");
|
||||
mLess->setMouseDownCallback( LLScrollingPanelParam::onHintMinMouseDown );
|
||||
mLess->setMouseUpCallback( LLScrollingPanelParam::onHintMinMouseUp );
|
||||
mLess->setHeldDownCallback( LLScrollingPanelParam::onHintMinHeldDown );
|
||||
mLess->setMouseDownCallback( boost::bind(&LLScrollingPanelParam::onHintMinMouseDown, this) );
|
||||
mLess->setMouseUpCallback( boost::bind(LLScrollingPanelParam::onHintMinMouseUp, this) );
|
||||
mLess->setHeldDownCallback( boost::bind(LLScrollingPanelParam::onHintMinHeldDown, this) );
|
||||
mLess->setHeldDownDelay( PARAM_STEP_TIME_THRESHOLD );
|
||||
|
||||
mMore = getChild<LLButton>("more");
|
||||
mMore->setMouseDownCallback( LLScrollingPanelParam::onHintMaxMouseDown );
|
||||
mMore->setMouseUpCallback( LLScrollingPanelParam::onHintMaxMouseUp );
|
||||
mMore->setHeldDownCallback( LLScrollingPanelParam::onHintMaxHeldDown );
|
||||
mMore->setMouseDownCallback( boost::bind(LLScrollingPanelParam::onHintMaxMouseDown, this) );
|
||||
mMore->setMouseUpCallback( boost::bind(LLScrollingPanelParam::onHintMaxMouseUp, this) );
|
||||
mMore->setHeldDownCallback( boost::bind(LLScrollingPanelParam::onHintMaxHeldDown, this) );
|
||||
mMore->setHeldDownDelay( PARAM_STEP_TIME_THRESHOLD );
|
||||
}
|
||||
else
|
||||
@@ -1400,7 +1444,8 @@ LLScrollingPanelParam::LLScrollingPanelParam( const std::string& name,
|
||||
}
|
||||
for (it = to_remove.begin(); it != to_remove.end(); it++)
|
||||
{
|
||||
removeChild(*it, TRUE);
|
||||
removeChild(*it);
|
||||
delete (*it);
|
||||
}
|
||||
slider->translate(0,PARAM_HINT_HEIGHT);
|
||||
reshape(getRect().getWidth(),getRect().getHeight()-PARAM_HINT_HEIGHT);
|
||||
@@ -1526,12 +1571,21 @@ void LLScrollingPanelParam::onSliderMoved(LLUICtrl* ctrl, void* userdata)
|
||||
LLScrollingPanelParam* self = (LLScrollingPanelParam*) userdata;
|
||||
LLViewerVisualParam* param = self->mParam;
|
||||
|
||||
F32 current_weight = gAgentAvatarp->getVisualParamWeight( param );
|
||||
if(!param)
|
||||
return;
|
||||
|
||||
LLWearable* wearable = gAgentWearables.getWearable( (LLWearableType::EType)param->getWearableType(), 0 ); // TODO: MULTI-WEARABLE
|
||||
|
||||
if(!wearable)
|
||||
return;
|
||||
|
||||
F32 current_weight = wearable->getVisualParamWeight(param->getID());
|
||||
F32 new_weight = self->percentToWeight( (F32)slider->getValue().asReal() );
|
||||
if (current_weight != new_weight )
|
||||
{
|
||||
updateAvatarHeightDisplay();
|
||||
gAgentAvatarp->setVisualParamWeight( param, new_weight, FALSE);
|
||||
wearable->setVisualParamWeight( param->getID(), new_weight, FALSE);
|
||||
wearable->writeToAvatar();
|
||||
gAgentAvatarp->updateVisualParams();
|
||||
}
|
||||
}
|
||||
@@ -1593,7 +1647,14 @@ void LLScrollingPanelParam::onHintMaxHeldDown( void* userdata )
|
||||
|
||||
void LLScrollingPanelParam::onHintHeldDown( LLVisualParamHint* hint )
|
||||
{
|
||||
F32 current_weight = gAgentAvatarp->getVisualParamWeight( hint->getVisualParam() );
|
||||
LLViewerVisualParam* param = hint->getVisualParam();
|
||||
|
||||
LLWearable* wearable = gAgentWearables.getWearable((LLWearableType::EType)param->getWearableType(),0); // TODO: MULTI-WEARABLE
|
||||
|
||||
if(!wearable)
|
||||
return;
|
||||
|
||||
F32 current_weight = wearable->getVisualParamWeight( param->getID() );
|
||||
|
||||
if (current_weight != hint->getVisualParamWeight() )
|
||||
{
|
||||
@@ -1620,7 +1681,8 @@ void LLScrollingPanelParam::onHintHeldDown( LLVisualParamHint* hint )
|
||||
if (slider->getMinValue() < new_percent
|
||||
&& new_percent < slider->getMaxValue())
|
||||
{
|
||||
gAgentAvatarp->setVisualParamWeight( hint->getVisualParam(), new_weight, TRUE);
|
||||
wearable->setVisualParamWeight(param->getID(), new_weight, TRUE);
|
||||
wearable->writeToAvatar();
|
||||
gAgentAvatarp->updateVisualParams();
|
||||
|
||||
slider->setValue( weightToPercent( new_weight ) );
|
||||
@@ -1643,20 +1705,27 @@ void LLScrollingPanelParam::onHintMinMouseUp( void* userdata )
|
||||
|
||||
if (elapsed_time < PARAM_STEP_TIME_THRESHOLD)
|
||||
{
|
||||
// step in direction
|
||||
F32 current_weight = gAgentAvatarp->getVisualParamWeight( hint->getVisualParam() );
|
||||
F32 range = self->mHintMax->getVisualParamWeight() - self->mHintMin->getVisualParamWeight();
|
||||
// step a fraction in the negative directiona
|
||||
F32 new_weight = current_weight - (range / 10.f);
|
||||
F32 new_percent = self->weightToPercent(new_weight);
|
||||
LLSliderCtrl* slider = self->getChild<LLSliderCtrl>("param slider");
|
||||
if (slider)
|
||||
LLViewerVisualParam* param = hint->getVisualParam();
|
||||
|
||||
LLWearable* wearable = gAgentWearables.getWearable((LLWearableType::EType)param->getWearableType(),0); // TODO: MULTI-WEARABLE
|
||||
if(wearable)
|
||||
{
|
||||
if (slider->getMinValue() < new_percent
|
||||
&& new_percent < slider->getMaxValue())
|
||||
// step in direction
|
||||
F32 current_weight = wearable->getVisualParamWeight( param->getID() );
|
||||
F32 range = self->mHintMax->getVisualParamWeight() - self->mHintMin->getVisualParamWeight();
|
||||
// step a fraction in the negative direction
|
||||
F32 new_weight = current_weight - (range / 10.f);
|
||||
F32 new_percent = self->weightToPercent(new_weight);
|
||||
LLSliderCtrl* slider = self->getChild<LLSliderCtrl>("param slider");
|
||||
if (slider)
|
||||
{
|
||||
avatar->setVisualParamWeight(hint->getVisualParam(), new_weight, TRUE);
|
||||
slider->setValue( self->weightToPercent( new_weight ) );
|
||||
if (slider->getMinValue() < new_percent
|
||||
&& new_percent < slider->getMaxValue())
|
||||
{
|
||||
wearable->setVisualParamWeight(param->getID(), new_weight, TRUE);
|
||||
wearable->writeToAvatar();
|
||||
slider->setValue( self->weightToPercent( new_weight ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1678,20 +1747,27 @@ void LLScrollingPanelParam::onHintMaxMouseUp( void* userdata )
|
||||
|
||||
if (elapsed_time < PARAM_STEP_TIME_THRESHOLD)
|
||||
{
|
||||
// step in direction
|
||||
F32 current_weight = gAgentAvatarp->getVisualParamWeight( hint->getVisualParam() );
|
||||
F32 range = self->mHintMax->getVisualParamWeight() - self->mHintMin->getVisualParamWeight();
|
||||
// step a fraction in the negative direction
|
||||
F32 new_weight = current_weight + (range / 10.f);
|
||||
F32 new_percent = self->weightToPercent(new_weight);
|
||||
LLSliderCtrl* slider = self->getChild<LLSliderCtrl>("param slider");
|
||||
if (slider)
|
||||
LLViewerVisualParam* param = hint->getVisualParam();
|
||||
|
||||
LLWearable* wearable = gAgentWearables.getWearable((LLWearableType::EType)param->getWearableType(),0);
|
||||
if(wearable)
|
||||
{
|
||||
if (slider->getMinValue() < new_percent
|
||||
&& new_percent < slider->getMaxValue())
|
||||
// step in direction
|
||||
F32 current_weight = wearable->getVisualParamWeight( param->getID() );
|
||||
F32 range = self->mHintMax->getVisualParamWeight() - self->mHintMin->getVisualParamWeight();
|
||||
// step a fraction in the negative direction
|
||||
F32 new_weight = current_weight + (range / 10.f);
|
||||
F32 new_percent = self->weightToPercent(new_weight);
|
||||
LLSliderCtrl* slider = self->getChild<LLSliderCtrl>("param slider");
|
||||
if (slider)
|
||||
{
|
||||
avatar->setVisualParamWeight(hint->getVisualParam(), new_weight, TRUE);
|
||||
slider->setValue( self->weightToPercent( new_weight ) );
|
||||
if (slider->getMinValue() < new_percent
|
||||
&& new_percent < slider->getMaxValue())
|
||||
{
|
||||
wearable->setVisualParamWeight(param->getID(), new_weight, TRUE);
|
||||
wearable->writeToAvatar();
|
||||
slider->setValue( self->weightToPercent( new_weight ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1736,9 +1812,7 @@ struct WearablePanelData
|
||||
LLFloaterCustomize::LLFloaterCustomize()
|
||||
: LLFloater(std::string("customize")),
|
||||
mScrollingPanelList( NULL ),
|
||||
mInventoryObserver(NULL),
|
||||
mNextStepAfterSaveCallback( NULL ),
|
||||
mNextStepAfterSaveUserdata( NULL )
|
||||
mInventoryObserver(NULL)
|
||||
{
|
||||
memset(&mWearablePanelList[0],0,sizeof(char*)*LLWearableType::WT_COUNT); //Initialize to 0
|
||||
|
||||
@@ -1751,22 +1825,16 @@ LLFloaterCustomize::LLFloaterCustomize()
|
||||
gInventory.addObserver(mInventoryObserver);
|
||||
|
||||
LLCallbackMap::map_t factory_map;
|
||||
factory_map["Shape"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_SHAPE) ) );
|
||||
factory_map["Skin"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_SKIN) ) );
|
||||
factory_map["Hair"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_HAIR) ) );
|
||||
factory_map["Eyes"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_EYES) ) );
|
||||
factory_map["Shirt"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_SHIRT) ) );
|
||||
factory_map["Pants"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_PANTS) ) );
|
||||
factory_map["Shoes"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_SHOES) ) );
|
||||
factory_map["Socks"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_SOCKS) ) );
|
||||
factory_map["Jacket"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_JACKET) ) );
|
||||
factory_map["Gloves"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_GLOVES) ) );
|
||||
factory_map["Undershirt"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_UNDERSHIRT) ) );
|
||||
factory_map["Underpants"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_UNDERPANTS) ) );
|
||||
factory_map["Skirt"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_SKIRT) ) );
|
||||
factory_map["Alpha"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_ALPHA)));
|
||||
factory_map["Tattoo"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_TATTOO)));
|
||||
factory_map["Physics"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, LLWearableType::WT_PHYSICS)));
|
||||
const std::string &invalid_name = LLWearableType::getTypeName(LLWearableType::WT_INVALID);
|
||||
for(U32 type=LLWearableType::WT_SHAPE;type<LLWearableType::WT_INVALID;++type)
|
||||
{
|
||||
std::string name = LLWearableType::getTypeName((LLWearableType::EType)type);
|
||||
if(name != invalid_name)
|
||||
{
|
||||
name[0] = toupper(name[0]);
|
||||
factory_map[name] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, (LLWearableType::EType)type) ) );
|
||||
}
|
||||
}
|
||||
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_customize.xml", &factory_map);
|
||||
}
|
||||
@@ -1785,22 +1853,16 @@ BOOL LLFloaterCustomize::postBuild()
|
||||
initWearablePanels();
|
||||
|
||||
// Tab container
|
||||
childSetTabChangeCallback("customize tab container", "Shape", onTabChanged, (void*)LLWearableType::WT_SHAPE, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Skin", onTabChanged, (void*)LLWearableType::WT_SKIN, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Hair", onTabChanged, (void*)LLWearableType::WT_HAIR, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Eyes", onTabChanged, (void*)LLWearableType::WT_EYES, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Shirt", onTabChanged, (void*)LLWearableType::WT_SHIRT, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Pants", onTabChanged, (void*)LLWearableType::WT_PANTS, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Shoes", onTabChanged, (void*)LLWearableType::WT_SHOES, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Socks", onTabChanged, (void*)LLWearableType::WT_SOCKS, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Jacket", onTabChanged, (void*)LLWearableType::WT_JACKET, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Gloves", onTabChanged, (void*)LLWearableType::WT_GLOVES, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Undershirt", onTabChanged, (void*)LLWearableType::WT_UNDERSHIRT, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Underpants", onTabChanged, (void*)LLWearableType::WT_UNDERPANTS, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Skirt", onTabChanged, (void*)LLWearableType::WT_SKIRT, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Alpha", onTabChanged, (void*)LLWearableType::WT_ALPHA, onTabPrecommit);
|
||||
childSetTabChangeCallback("customize tab container", "Tattoo", onTabChanged, (void*)LLWearableType::WT_TATTOO, onTabPrecommit);
|
||||
childSetTabChangeCallback("customize tab container", "Physics", onTabChanged, (void*)LLWearableType::WT_PHYSICS, onTabPrecommit);
|
||||
const std::string &invalid_name = LLWearableType::getTypeName(LLWearableType::WT_INVALID);
|
||||
for(U32 type=LLWearableType::WT_SHAPE;type<LLWearableType::WT_INVALID;++type)
|
||||
{
|
||||
std::string name = LLWearableType::getTypeName((LLWearableType::EType)type);
|
||||
if(name != invalid_name)
|
||||
{
|
||||
name[0] = toupper(name[0]);
|
||||
childSetTabChangeCallback("customize tab container", name, onTabChanged, (void*)type, onTabPrecommit );
|
||||
}
|
||||
}
|
||||
|
||||
// Remove underwear panels for teens
|
||||
if (gAgent.isTeen())
|
||||
@@ -1990,12 +2052,11 @@ void LLFloaterCustomize::onBtnOk( void* userdata )
|
||||
LLFloaterCustomize* floater = (LLFloaterCustomize*) userdata;
|
||||
gAgentWearables.saveAllWearables();
|
||||
|
||||
LLVOAvatar* avatar = gAgentAvatarp;
|
||||
if ( avatar )
|
||||
if ( gAgentAvatarp )
|
||||
{
|
||||
avatar->invalidateAll();
|
||||
gAgentAvatarp->invalidateAll();
|
||||
|
||||
avatar->requestLayerSetUploads();
|
||||
gAgentAvatarp->requestLayerSetUploads();
|
||||
|
||||
gAgent.sendAgentSetAppearance();
|
||||
}
|
||||
@@ -2042,7 +2103,8 @@ void LLFloaterCustomize::onMakeOutfitCommit( LLMakeOutfitDialog* dialog, void* u
|
||||
|
||||
dialog->getIncludedItems( wearables_to_include, attachments_to_include );
|
||||
|
||||
gAgentWearables.makeNewOutfit( dialog->getFolderName(), wearables_to_include, attachments_to_include, dialog->getRenameClothing() );
|
||||
// MULTI-WEARABLES TODO
|
||||
//LLAppearanceMgr::getInstance()->makeNewOutfit( dialog->getFolderName(), wearables_to_include, attachments_to_include, dialog->getRenameClothing() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2069,79 +2131,42 @@ void* LLFloaterCustomize::createWearablePanel(void* userdata)
|
||||
|
||||
void LLFloaterCustomize::initWearablePanels()
|
||||
{
|
||||
LLSubpart* part;
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Shape
|
||||
LLPanelEditWearable* panel = mWearablePanelList[ LLWearableType::WT_SHAPE ];
|
||||
|
||||
// body
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "shape_body";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-2.5f, 0.5f, 0.8f);
|
||||
LLSubpart* part = new LLSubpart("mPelvis", "shape_body", LLVector3d(0.f,0.f,0.1f), LLVector3d(-2.5f, 0.5f, 0.8f));
|
||||
panel->addSubpart( "Body", SUBPART_SHAPE_WHOLE, part );
|
||||
|
||||
// head supparts
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "shape_head";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.05f );
|
||||
part->mCameraOffset.setVec(-0.5f, 0.05f, 0.07f );
|
||||
const LLVector3d head_target(0.f, 0.f, 0.05f);
|
||||
const LLVector3d head_camera(-0.5f, 0.05f, 0.07f);
|
||||
|
||||
part = new LLSubpart("mHead", "shape_head", head_target, head_camera);
|
||||
panel->addSubpart( "Head", SUBPART_SHAPE_HEAD, part );
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "shape_eyes";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.05f );
|
||||
part->mCameraOffset.setVec(-0.5f, 0.05f, 0.07f );
|
||||
part = new LLSubpart("mHead", "shape_eyes", head_target, head_camera);
|
||||
panel->addSubpart( "Eyes", SUBPART_SHAPE_EYES, part );
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "shape_ears";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.05f );
|
||||
part->mCameraOffset.setVec(-0.5f, 0.05f, 0.07f );
|
||||
part = new LLSubpart("mHead", "shape_ears", head_target, head_camera);
|
||||
panel->addSubpart( "Ears", SUBPART_SHAPE_EARS, part );
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "shape_nose";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.05f );
|
||||
part->mCameraOffset.setVec(-0.5f, 0.05f, 0.07f );
|
||||
part = new LLSubpart("mHead", "shape_nose", head_target, head_camera);
|
||||
panel->addSubpart( "Nose", SUBPART_SHAPE_NOSE, part );
|
||||
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "shape_mouth";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.05f );
|
||||
part->mCameraOffset.setVec(-0.5f, 0.05f, 0.07f );
|
||||
part = new LLSubpart("mHead", "shape_mouth", head_target, head_camera);
|
||||
panel->addSubpart( "Mouth", SUBPART_SHAPE_MOUTH, part );
|
||||
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "shape_chin";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.05f );
|
||||
part->mCameraOffset.setVec(-0.5f, 0.05f, 0.07f );
|
||||
part = new LLSubpart("mHead", "shape_chin", head_target, head_camera);
|
||||
panel->addSubpart( "Chin", SUBPART_SHAPE_CHIN, part );
|
||||
|
||||
// torso
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "shape_torso";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.3f);
|
||||
part->mCameraOffset.setVec(-1.f, 0.15f, 0.3f);
|
||||
part = new LLSubpart("mTorso", "shape_torso", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f));
|
||||
panel->addSubpart( "Torso", SUBPART_SHAPE_TORSO, part );
|
||||
|
||||
// legs
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "shape_legs";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -0.5f);
|
||||
part->mCameraOffset.setVec(-1.6f, 0.15f, -0.5f);
|
||||
part = new LLSubpart("mPelvis", "shape_legs", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f));
|
||||
panel->addSubpart( "Legs", SUBPART_SHAPE_LEGS, part );
|
||||
|
||||
panel->childSetCommitCallback("sex radio", LLPanelEditWearable::onCommitSexChange, panel);
|
||||
@@ -2150,32 +2175,16 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
// Skin
|
||||
panel = mWearablePanelList[ LLWearableType::WT_SKIN ];
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "skin_color";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.05f);
|
||||
part->mCameraOffset.setVec(-0.5f, 0.05f, 0.07f);
|
||||
part = new LLSubpart("mHead", "skin_color", head_target, head_camera);
|
||||
panel->addSubpart( "Skin Color", SUBPART_SKIN_COLOR, part );
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "skin_facedetail";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.05f);
|
||||
part->mCameraOffset.setVec(-0.5f, 0.05f, 0.07f);
|
||||
part = new LLSubpart("mHead", "skin_facedetail", head_target, head_camera);
|
||||
panel->addSubpart( "Face Detail", SUBPART_SKIN_FACEDETAIL, part );
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "skin_makeup";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.05f);
|
||||
part->mCameraOffset.setVec(-0.5f, 0.05f, 0.07f);
|
||||
part = new LLSubpart("mHead", "skin_makeup", head_target, head_camera);
|
||||
panel->addSubpart( "Makeup", SUBPART_SKIN_MAKEUP, part );
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "skin_bodydetail";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -0.2f);
|
||||
part->mCameraOffset.setVec(-2.5f, 0.5f, 0.5f);
|
||||
part = new LLSubpart("mPelvis", "skin_bodydetail", LLVector3d(0.f, 0.f, -0.2f), LLVector3d(-2.5f, 0.5f, 0.5f));
|
||||
panel->addSubpart( "Body Detail", SUBPART_SKIN_BODYDETAIL, part );
|
||||
|
||||
panel->addTextureDropTarget( TEX_HEAD_BODYPAINT, "Head Tattoos", LLUUID::null, TRUE );
|
||||
@@ -2186,33 +2195,16 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
// Hair
|
||||
panel = mWearablePanelList[ LLWearableType::WT_HAIR ];
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "hair_color";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.10f);
|
||||
part->mCameraOffset.setVec(-0.4f, 0.05f, 0.10f);
|
||||
part = new LLSubpart("mHead", "hair_color", LLVector3d(0.f, 0.f, 0.10f), LLVector3d(-0.4f, 0.05f, 0.10f));
|
||||
panel->addSubpart( "Color", SUBPART_HAIR_COLOR, part );
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "hair_style";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.10f);
|
||||
part->mCameraOffset.setVec(-0.4f, 0.05f, 0.10f);
|
||||
part = new LLSubpart("mHead", "hair_style", head_target, head_camera);
|
||||
panel->addSubpart( "Style", SUBPART_HAIR_STYLE, part );
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "hair_eyebrows";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.05f);
|
||||
part->mCameraOffset.setVec(-0.5f, 0.05f, 0.07f);
|
||||
part = new LLSubpart("mHead", "hair_eyebrows", head_target, head_camera);
|
||||
panel->addSubpart( "Eyebrows", SUBPART_HAIR_EYEBROWS, part );
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mSex = SEX_MALE;
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "hair_facial";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.05f);
|
||||
part->mCameraOffset.setVec(-0.5f, 0.05f, 0.07f);
|
||||
part = new LLSubpart("mHead", "hair_facial", head_target, head_camera, SEX_MALE);
|
||||
panel->addSubpart( "Facial", SUBPART_HAIR_FACIAL, part );
|
||||
|
||||
panel->addTextureDropTarget(TEX_HAIR, "Texture",
|
||||
@@ -2223,11 +2215,7 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
// Eyes
|
||||
panel = mWearablePanelList[ LLWearableType::WT_EYES ];
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mHead";
|
||||
part->mEditGroup = "eyes";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.05f);
|
||||
part->mCameraOffset.setVec(-0.5f, 0.05f, 0.07f);
|
||||
part = new LLSubpart("mHead", "eyes", head_target, head_camera);
|
||||
panel->addSubpart( LLStringUtil::null, SUBPART_EYES, part );
|
||||
|
||||
panel->addTextureDropTarget(TEX_EYES_IRIS, "Iris",
|
||||
@@ -2238,11 +2226,7 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
// Shirt
|
||||
panel = mWearablePanelList[ LLWearableType::WT_SHIRT ];
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "shirt";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.3f);
|
||||
part->mCameraOffset.setVec(-1.f, 0.15f, 0.3f);
|
||||
part = new LLSubpart("mTorso", "shirt", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f));
|
||||
panel->addSubpart( LLStringUtil::null, SUBPART_SHIRT, part );
|
||||
|
||||
panel->addTextureDropTarget( TEX_UPPER_SHIRT, "Fabric",
|
||||
@@ -2256,11 +2240,7 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
// Pants
|
||||
panel = mWearablePanelList[ LLWearableType::WT_PANTS ];
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "pants";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -0.5f);
|
||||
part->mCameraOffset.setVec(-1.6f, 0.15f, -0.5f);
|
||||
part = new LLSubpart("mPelvis", "pants", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f));
|
||||
panel->addSubpart( LLStringUtil::null, SUBPART_PANTS, part );
|
||||
|
||||
panel->addTextureDropTarget(TEX_LOWER_PANTS, "Fabric",
|
||||
@@ -2276,11 +2256,7 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "shoes";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -0.5f);
|
||||
part->mCameraOffset.setVec(-1.6f, 0.15f, -0.5f);
|
||||
part = new LLSubpart("mPelvis", "shoes", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f));
|
||||
panel->addSubpart( LLStringUtil::null, SUBPART_SHOES, part );
|
||||
|
||||
panel->addTextureDropTarget( TEX_LOWER_SHOES, "Fabric",
|
||||
@@ -2297,11 +2273,7 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "socks";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -0.5f);
|
||||
part->mCameraOffset.setVec(-1.6f, 0.15f, -0.5f);
|
||||
part = new LLSubpart("mPelvis", "socks", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f));
|
||||
panel->addSubpart( LLStringUtil::null, SUBPART_SOCKS, part );
|
||||
|
||||
panel->addTextureDropTarget( TEX_LOWER_SOCKS, "Fabric",
|
||||
@@ -2317,11 +2289,7 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "jacket";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.f);
|
||||
part->mCameraOffset.setVec(-2.f, 0.1f, 0.3f);
|
||||
part = new LLSubpart("mTorso", "jacket", LLVector3d(), LLVector3d(-2.f, 0.1f, 0.3f));
|
||||
panel->addSubpart( LLStringUtil::null, SUBPART_JACKET, part );
|
||||
|
||||
panel->addTextureDropTarget( TEX_UPPER_JACKET, "Upper Fabric",
|
||||
@@ -2340,11 +2308,7 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "skirt";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -0.5f);
|
||||
part->mCameraOffset.setVec(-1.6f, 0.15f, -0.5f);
|
||||
part = new LLSubpart("mPelvis", "skirt", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f));
|
||||
panel->addSubpart( LLStringUtil::null, SUBPART_SKIRT, part );
|
||||
|
||||
panel->addTextureDropTarget( TEX_SKIRT, "Fabric",
|
||||
@@ -2361,11 +2325,7 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "gloves";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.f);
|
||||
part->mCameraOffset.setVec(-1.f, 0.15f, 0.f);
|
||||
part = new LLSubpart("mTorso", "gloves", LLVector3d(), LLVector3d(-1.f, 0.15f, 0.f));
|
||||
panel->addSubpart( LLStringUtil::null, SUBPART_GLOVES, part );
|
||||
|
||||
panel->addTextureDropTarget( TEX_UPPER_GLOVES, "Fabric",
|
||||
@@ -2382,11 +2342,7 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "undershirt";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.3f);
|
||||
part->mCameraOffset.setVec(-1.f, 0.15f, 0.3f);
|
||||
part = new LLSubpart("mTorso", "undershirt", LLVector3d(0.f, 0.f, 0.3f), LLVector3d(-1.f, 0.15f, 0.3f));
|
||||
panel->addSubpart( LLStringUtil::null, SUBPART_UNDERSHIRT, part );
|
||||
|
||||
panel->addTextureDropTarget( TEX_UPPER_UNDERSHIRT, "Fabric",
|
||||
@@ -2402,11 +2358,7 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "underpants";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -0.5f);
|
||||
part->mCameraOffset.setVec(-1.6f, 0.15f, -0.5f);
|
||||
part = new LLSubpart("mPelvis", "underpants", LLVector3d(0.f, 0.f, -0.5f), LLVector3d(-1.6f, 0.15f, -0.5f));
|
||||
panel->addSubpart( LLStringUtil::null, SUBPART_UNDERPANTS, part );
|
||||
|
||||
panel->addTextureDropTarget( TEX_LOWER_UNDERPANTS, "Fabric",
|
||||
@@ -2422,11 +2374,7 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "alpha";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-2.5f, 0.5f, 0.8f);
|
||||
part = new LLSubpart("mPelvis", "alpha", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f));
|
||||
panel->addSubpart(LLStringUtil::null, SUBPART_ALPHA, part);
|
||||
|
||||
panel->addTextureDropTarget(TEX_LOWER_ALPHA, "Lower Alpha",
|
||||
@@ -2458,11 +2406,7 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "tattoo";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-2.5f, 0.5f, 0.8f);
|
||||
part = new LLSubpart("mPelvis", "tattoo", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f));
|
||||
panel->addSubpart(LLStringUtil::null, SUBPART_TATTOO, part);
|
||||
|
||||
panel->addTextureDropTarget(TEX_LOWER_TATTOO, "Lower Tattoo",
|
||||
@@ -2484,63 +2428,25 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
|
||||
if(panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mSex = SEX_FEMALE;
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "physics_breasts_updown";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-0.8f, 0.15f, 0.38f);
|
||||
part->mVisualHint = false;
|
||||
part = new LLSubpart("mTorso", "physics_breasts_updown", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-0.8f, 0.15f, 0.38f), SEX_FEMALE, false);
|
||||
panel->addSubpart("Breast Bounce", SUBPART_PHYSICS_BREASTS_UPDOWN, part);
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mSex = SEX_FEMALE;
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "physics_breasts_inout";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-0.8f, 0.15f, 0.38f);
|
||||
part->mVisualHint = false;
|
||||
part = new LLSubpart("mTorso", "physics_breasts_inout", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-0.8f, 0.15f, 0.38f), SEX_FEMALE, false);
|
||||
panel->addSubpart("Breast Cleavage", SUBPART_PHYSICS_BREASTS_INOUT, part);
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mSex = SEX_FEMALE;
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "physics_breasts_leftright";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-0.8f, 0.15f, 0.38f);
|
||||
part->mVisualHint = false;
|
||||
part = new LLSubpart("mTorso", "physics_breasts_leftright", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-0.8f, 0.15f, 0.38f), SEX_FEMALE, false);
|
||||
panel->addSubpart("Breast Sway", SUBPART_PHYSICS_BREASTS_LEFTRIGHT, part);
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "physics_belly_updown";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -.05f);
|
||||
part->mCameraOffset.setVec(-0.8f, 0.15f, 0.38f);
|
||||
part->mVisualHint = false;
|
||||
part = new LLSubpart("mTorso", "physics_belly_updown", LLVector3d(0.f, 0.f, -.05f), LLVector3d(-0.8f, 0.15f, 0.38f), false);
|
||||
panel->addSubpart("Belly Bounce", SUBPART_PHYSICS_BELLY_UPDOWN, part);
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "physics_butt_updown";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -0.1f);
|
||||
part->mCameraOffset.setVec(0.3f, 0.8f, -0.1f);
|
||||
part->mVisualHint = false;
|
||||
part = new LLSubpart("mPelvis", "physics_butt_updown", LLVector3d(0.f, 0.f,-.1f), LLVector3d(0.3f, 0.8f, -0.1f), false);
|
||||
panel->addSubpart("Butt Bounce", SUBPART_PHYSICS_BUTT_UPDOWN, part);
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "physics_butt_leftright";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, -0.1f);
|
||||
part->mCameraOffset.setVec(0.3f, 0.8f, -0.1f);
|
||||
part->mVisualHint = false;
|
||||
part = new LLSubpart("mPelvis", "physics_butt_leftright", LLVector3d(0.f, 0.f,-.1f), LLVector3d(0.3f, 0.8f, -0.1f), false);
|
||||
panel->addSubpart("Butt Sway", SUBPART_PHYSICS_BUTT_LEFTRIGHT, part);
|
||||
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mTorso";
|
||||
part->mEditGroup = "physics_advanced";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-2.5f, 0.5f, 0.8f);
|
||||
part->mVisualHint = false;
|
||||
part = new LLSubpart("mTorso", "physics_advanced", LLVector3d(0.f, 0.f, 0.1f), LLVector3d(-2.5f, 0.5f, 0.8f), false);
|
||||
panel->addSubpart("Advanced Parameters", SUBPART_PHYSICS_ADVANCED, part);
|
||||
|
||||
}
|
||||
@@ -2602,11 +2508,11 @@ void LLFloaterCustomize::onTabPrecommit( void* userdata, bool from_click )
|
||||
LLWearableType::EType type = (LLWearableType::EType)(intptr_t) userdata;
|
||||
if (type != LLWearableType::WT_INVALID && gFloaterCustomize && gFloaterCustomize->getCurrentWearableType() != type)
|
||||
{
|
||||
gFloaterCustomize->askToSaveIfDirty(onCommitChangeTab, userdata);
|
||||
gFloaterCustomize->askToSaveIfDirty(boost::bind(&onCommitChangeTab, _1));
|
||||
}
|
||||
else
|
||||
{
|
||||
onCommitChangeTab(TRUE, NULL);
|
||||
onCommitChangeTab(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2629,7 +2535,7 @@ void LLFloaterCustomize::onClose(bool app_quitting)
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterCustomize::onCommitChangeTab(BOOL proceed, void* userdata)
|
||||
void LLFloaterCustomize::onCommitChangeTab(BOOL proceed)
|
||||
{
|
||||
if (!proceed || !gFloaterCustomize)
|
||||
{
|
||||
@@ -2716,24 +2622,20 @@ void LLFloaterCustomize::updateScrollingPanelList(BOOL allow_modify)
|
||||
}
|
||||
|
||||
|
||||
void LLFloaterCustomize::askToSaveIfDirty( void(*next_step_callback)(BOOL proceed, void* userdata), void* userdata )
|
||||
void LLFloaterCustomize::askToSaveIfDirty( boost::function<void (BOOL)> cb )
|
||||
{
|
||||
if( isDirty())
|
||||
{
|
||||
// Ask if user wants to save, then continue to next step afterwards
|
||||
mNextStepAfterSaveCallback = next_step_callback;
|
||||
mNextStepAfterSaveUserdata = userdata;
|
||||
mNextStepAfterSaveCallback.connect(cb);
|
||||
|
||||
// Bring up view-modal dialog: Save changes? Yes, No, Cancel
|
||||
LLNotificationsUtil::add("SaveClothingBodyChanges", LLSD(), LLSD(),
|
||||
boost::bind(&LLFloaterCustomize::onSaveDialog, this, _1, _2));
|
||||
return;
|
||||
}
|
||||
|
||||
// Try to move to the next step
|
||||
if( next_step_callback )
|
||||
else
|
||||
{
|
||||
next_step_callback( TRUE, userdata );
|
||||
cb(TRUE); //just clal it immediately.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2767,10 +2669,9 @@ bool LLFloaterCustomize::onSaveDialog(const LLSD& notification, const LLSD& resp
|
||||
break;
|
||||
}
|
||||
|
||||
if( mNextStepAfterSaveCallback )
|
||||
{
|
||||
mNextStepAfterSaveCallback( proceed, mNextStepAfterSaveUserdata );
|
||||
}
|
||||
mNextStepAfterSaveCallback(proceed);
|
||||
mNextStepAfterSaveCallback.disconnect_all_slots(); //Should this be done?
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
|
||||
virtual BOOL isDirty() const;
|
||||
|
||||
void askToSaveIfDirty( void(*next_step_callback)(BOOL proceed, void* userdata), void* userdata );
|
||||
void askToSaveIfDirty( boost::function<void (BOOL)> cb );
|
||||
|
||||
void switchToDefaultSubpart();
|
||||
|
||||
@@ -118,7 +118,7 @@ public:
|
||||
static void onTabChanged( void* userdata, bool from_click );
|
||||
static void onTabPrecommit( void* userdata, bool from_click );
|
||||
bool onSaveDialog(const LLSD& notification, const LLSD& response);
|
||||
static void onCommitChangeTab(BOOL proceed, void* userdata);
|
||||
static void onCommitChangeTab(BOOL proceed);
|
||||
|
||||
void fetchInventory();
|
||||
void updateInventoryUI();
|
||||
@@ -135,10 +135,8 @@ protected:
|
||||
|
||||
LLInventoryObserver* mInventoryObserver;
|
||||
|
||||
void (*mNextStepAfterSaveCallback)(BOOL proceed, void* userdata);
|
||||
void* mNextStepAfterSaveUserdata;
|
||||
|
||||
|
||||
boost::signals2::signal<void (bool proceed)> mNextStepAfterSaveCallback;
|
||||
|
||||
protected:
|
||||
|
||||
static void* createWearablePanel(void* userdata);
|
||||
|
||||
@@ -264,7 +264,7 @@ void LLFloaterImagePreview::draw()
|
||||
|
||||
if (selected <= 0)
|
||||
{
|
||||
gl_rect_2d_checkerboard( getScreenRect(), mPreviewRect);
|
||||
gl_rect_2d_checkerboard( calcScreenRect(), mPreviewRect);
|
||||
LLGLDisable gls_alpha(GL_ALPHA_TEST);
|
||||
|
||||
if(mImagep.notNull())
|
||||
|
||||
@@ -147,25 +147,25 @@ void LLFloaterLagMeter::determineClient()
|
||||
|
||||
if (!gFocusMgr.getAppHasFocus())
|
||||
{
|
||||
mClientButton->setImageUnselected(LAG_GOOD_IMAGE_NAME);
|
||||
mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
|
||||
mClientText->setText( getString("client_frame_time_window_bg_msg", mStringArgs) );
|
||||
mClientCause->setText( LLStringUtil::null );
|
||||
}
|
||||
else if(client_frame_time >= mClientFrameTimeCritical)
|
||||
{
|
||||
mClientButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME);
|
||||
mClientButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
|
||||
mClientText->setText( getString("client_frame_time_critical_msg", mStringArgs) );
|
||||
find_cause = true;
|
||||
}
|
||||
else if(client_frame_time >= mClientFrameTimeWarning)
|
||||
{
|
||||
mClientButton->setImageUnselected(LAG_WARNING_IMAGE_NAME);
|
||||
mClientButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
|
||||
mClientText->setText( getString("client_frame_time_warning_msg", mStringArgs) );
|
||||
find_cause = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mClientButton->setImageUnselected(LAG_GOOD_IMAGE_NAME);
|
||||
mClientButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
|
||||
mClientText->setText( getString("client_frame_time_normal_msg", mStringArgs) );
|
||||
mClientCause->setText( LLStringUtil::null );
|
||||
}
|
||||
@@ -206,13 +206,13 @@ void LLFloaterLagMeter::determineNetwork()
|
||||
|
||||
if(packet_loss >= mNetworkPacketLossCritical)
|
||||
{
|
||||
mNetworkButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME);
|
||||
mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
|
||||
mNetworkText->setText( getString("network_packet_loss_critical_msg", mStringArgs) );
|
||||
find_cause_loss = true;
|
||||
}
|
||||
else if(ping_time >= mNetworkPingCritical)
|
||||
{
|
||||
mNetworkButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME);
|
||||
mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
|
||||
if (client_frame_time_ms < mNetworkPingCritical)
|
||||
{
|
||||
mNetworkText->setText( getString("network_ping_critical_msg", mStringArgs) );
|
||||
@@ -221,13 +221,13 @@ void LLFloaterLagMeter::determineNetwork()
|
||||
}
|
||||
else if(packet_loss >= mNetworkPacketLossWarning)
|
||||
{
|
||||
mNetworkButton->setImageUnselected(LAG_WARNING_IMAGE_NAME);
|
||||
mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
|
||||
mNetworkText->setText( getString("network_packet_loss_warning_msg", mStringArgs) );
|
||||
find_cause_loss = true;
|
||||
}
|
||||
else if(ping_time >= mNetworkPingWarning)
|
||||
{
|
||||
mNetworkButton->setImageUnselected(LAG_WARNING_IMAGE_NAME);
|
||||
mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
|
||||
if (client_frame_time_ms < mNetworkPingWarning)
|
||||
{
|
||||
mNetworkText->setText( getString("network_ping_warning_msg", mStringArgs) );
|
||||
@@ -236,7 +236,7 @@ void LLFloaterLagMeter::determineNetwork()
|
||||
}
|
||||
else
|
||||
{
|
||||
mNetworkButton->setImageUnselected(LAG_GOOD_IMAGE_NAME);
|
||||
mNetworkButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
|
||||
mNetworkText->setText( getString("network_performance_normal_msg", mStringArgs) );
|
||||
}
|
||||
|
||||
@@ -261,19 +261,19 @@ void LLFloaterLagMeter::determineServer()
|
||||
|
||||
if(sim_frame_time >= mServerFrameTimeCritical)
|
||||
{
|
||||
mServerButton->setImageUnselected(LAG_CRITICAL_IMAGE_NAME);
|
||||
mServerButton->setImageUnselected(LLUI::getUIImage(LAG_CRITICAL_IMAGE_NAME));
|
||||
mServerText->setText( getString("server_frame_time_critical_msg", mStringArgs) );
|
||||
find_cause = true;
|
||||
}
|
||||
else if(sim_frame_time >= mServerFrameTimeWarning)
|
||||
{
|
||||
mServerButton->setImageUnselected(LAG_WARNING_IMAGE_NAME);
|
||||
mServerButton->setImageUnselected(LLUI::getUIImage(LAG_WARNING_IMAGE_NAME));
|
||||
mServerText->setText( getString("server_frame_time_warning_msg", mStringArgs) );
|
||||
find_cause = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mServerButton->setImageUnselected(LAG_GOOD_IMAGE_NAME);
|
||||
mServerButton->setImageUnselected(LLUI::getUIImage(LAG_GOOD_IMAGE_NAME));
|
||||
mServerText->setText( getString("server_frame_time_normal_msg", mStringArgs) );
|
||||
mServerCause->setText( LLStringUtil::null );
|
||||
}
|
||||
|
||||
@@ -1105,7 +1105,7 @@ BOOL LLPanelLandObjects::postBuild()
|
||||
mSelectedObjects = getChild<LLTextBox>("selected_objects_text");
|
||||
mCleanOtherObjectsTime = getChild<LLLineEditor>("clean other time");
|
||||
|
||||
mCleanOtherObjectsTime->setFocusLostCallback(onLostFocus, this);
|
||||
mCleanOtherObjectsTime->setFocusLostCallback(boost::bind(&LLPanelLandObjects::onLostFocus, _1, this));
|
||||
mCleanOtherObjectsTime->setCommitCallback(onCommitClean);
|
||||
|
||||
childSetPrevalidate("clean other time", LLLineEditor::prevalidateNonNegativeS32);
|
||||
|
||||
@@ -93,7 +93,7 @@ LLFloaterLandmark::LLFloaterLandmark(const LLSD& data)
|
||||
|
||||
mInventoryPanel->setFilterTypes(filter_types);
|
||||
//mInventoryPanel->setFilterPermMask(getFilterPermMask()); //Commented out due to no-copy texture loss.
|
||||
mInventoryPanel->setSelectCallback(onSelectionChange, this);
|
||||
mInventoryPanel->setSelectCallback(boost::bind(&LLFloaterLandmark::onSelectionChange, _1, _2, (void*)this));
|
||||
mInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
|
||||
mInventoryPanel->setAllowMultiSelect(FALSE);
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
#include "llinventorybridge.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "llpanelinventory.h"
|
||||
#include "llpanelobjectinventory.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "lluiconstants.h"
|
||||
#include "llviewerobject.h"
|
||||
@@ -157,54 +157,38 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
|
||||
{
|
||||
parent_category_id = gInventory.getRootFolderID();
|
||||
}
|
||||
|
||||
|
||||
LLCategoryCreate* cat_data = new LLCategoryCreate(object_id, wear);
|
||||
|
||||
|
||||
LLUUID category_id = gInventory.createNewCategory(parent_category_id,
|
||||
LLFolderType::FT_NONE,
|
||||
name,
|
||||
callbackCreateInventoryCategory,
|
||||
(void*)cat_data);
|
||||
LLFolderType::FT_NONE,
|
||||
name,
|
||||
callbackCreateInventoryCategory,
|
||||
(void*)cat_data);
|
||||
|
||||
//If we get a null category ID, we are using a capability in createNewCategory and we will
|
||||
//handle the following in the callbackCreateInventoryCategory routine.
|
||||
if ( category_id.notNull() )
|
||||
{
|
||||
delete cat_data;
|
||||
|
||||
LLCatAndWear* data = new LLCatAndWear;
|
||||
data->mCatID = category_id;
|
||||
data->mWear = wear;
|
||||
data->mFolderResponded = false;
|
||||
|
||||
// Copy and/or move the items into the newly created folder.
|
||||
// Ignore any "you're going to break this item" messages.
|
||||
BOOL success = move_inv_category_world_to_agent(object_id, category_id, TRUE,
|
||||
callbackMoveInventory,
|
||||
(void*)data);
|
||||
if (!success)
|
||||
{
|
||||
delete data;
|
||||
data = NULL;
|
||||
|
||||
LLNotificationsUtil::add("OpenObjectCannotCopy");
|
||||
}
|
||||
LLSD result;
|
||||
result["folder_id"] = category_id;
|
||||
//Reduce redundant code by just calling the callback. Dur.
|
||||
callbackCreateInventoryCategory(result,cat_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLFloaterOpenObject::callbackCreateInventoryCategory(const LLSD& result, void* data)
|
||||
{
|
||||
LLCategoryCreate* cat_data = (LLCategoryCreate*)data;
|
||||
|
||||
|
||||
LLUUID category_id = result["folder_id"].asUUID();
|
||||
LLCatAndWear* wear_data = new LLCatAndWear;
|
||||
|
||||
wear_data->mCatID = category_id;
|
||||
wear_data->mWear = cat_data->mWear;
|
||||
wear_data->mFolderResponded = true;
|
||||
|
||||
|
||||
// Copy and/or move the items into the newly created folder.
|
||||
// Ignore any "you're going to break this item" messages.
|
||||
BOOL success = move_inv_category_world_to_agent(cat_data->mObjectID, category_id, TRUE,
|
||||
@@ -227,11 +211,10 @@ void LLFloaterOpenObject::callbackMoveInventory(S32 result, void* data)
|
||||
|
||||
if (result == 0)
|
||||
{
|
||||
LLInventoryView::showAgentInventory();
|
||||
LLInventoryView* view = LLInventoryView::getActiveInventory();
|
||||
if (view)
|
||||
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
|
||||
if (active_panel)
|
||||
{
|
||||
view->getPanel()->setSelection(cat->mCatID, TAKE_FOCUS_NO);
|
||||
active_panel->setSelection(cat->mCatID, TAKE_FOCUS_NO);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,6 +242,6 @@ void LLFloaterOpenObject::onClickMoveAndWear(void* data)
|
||||
void* LLFloaterOpenObject::createPanelInventory(void* data)
|
||||
{
|
||||
LLFloaterOpenObject* floater = (LLFloaterOpenObject*)data;
|
||||
floater->mPanelInventory = new LLPanelInventory(std::string("Object Contents"), LLRect());
|
||||
floater->mPanelInventory = new LLPanelObjectInventory(std::string("Object Contents"), LLRect());
|
||||
return floater->mPanelInventory;
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
#include "llfloater.h"
|
||||
|
||||
class LLObjectSelection;
|
||||
class LLPanelInventory;
|
||||
class LLPanelObjectInventory;
|
||||
|
||||
class LLFloaterOpenObject
|
||||
: public LLFloater
|
||||
@@ -84,7 +84,7 @@ protected:
|
||||
protected:
|
||||
static LLFloaterOpenObject* sInstance;
|
||||
|
||||
LLPanelInventory* mPanelInventory;
|
||||
LLPanelObjectInventory* mPanelInventory;
|
||||
LLSafeHandle<LLObjectSelection> mObjectSelection;
|
||||
BOOL mDirty;
|
||||
};
|
||||
|
||||
@@ -135,7 +135,7 @@ BOOL LLFloaterPostcard::postBuild()
|
||||
MsgField->setWordWrap(TRUE);
|
||||
|
||||
// For the first time a user focusess to .the msg box, all text will be selected.
|
||||
MsgField->setFocusChangedCallback(onMsgFormFocusRecieved, this);
|
||||
MsgField->setFocusChangedCallback(boost::bind(&LLFloaterPostcard::onMsgFormFocusRecieved, this, _1, MsgField));
|
||||
}
|
||||
|
||||
childSetFocus("to_form", TRUE);
|
||||
@@ -339,17 +339,12 @@ void LLFloaterPostcard::updateUserInfo(const std::string& email)
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterPostcard::onMsgFormFocusRecieved(LLFocusableElement* receiver, void* data)
|
||||
void LLFloaterPostcard::onMsgFormFocusRecieved(LLFocusableElement* receiver, LLTextEditor* msg_form)
|
||||
{
|
||||
LLFloaterPostcard* self = (LLFloaterPostcard *)data;
|
||||
if(self)
|
||||
if(msg_form && msg_form == receiver && msg_form->hasFocus() && !(mHasFirstMsgFocus))
|
||||
{
|
||||
LLTextEditor* msgForm = self->getChild<LLTextEditor>("msg_form");
|
||||
if(msgForm && msgForm == receiver && msgForm->hasFocus() && !(self->mHasFirstMsgFocus))
|
||||
{
|
||||
self->mHasFirstMsgFocus = true;
|
||||
msgForm->setText(LLStringUtil::null);
|
||||
}
|
||||
mHasFirstMsgFocus = true;
|
||||
msg_form->setText(LLStringUtil::null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ public:
|
||||
|
||||
static void updateUserInfo(const std::string& email);
|
||||
|
||||
static void onMsgFormFocusRecieved(LLFocusableElement* receiver, void* data);
|
||||
void onMsgFormFocusRecieved(LLFocusableElement* receiver, LLTextEditor* msg_form);
|
||||
bool missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response);
|
||||
|
||||
void sendPostcard();
|
||||
|
||||
@@ -613,7 +613,7 @@ void LLFloaterStats::reshape(S32 width, S32 height, BOOL called_from_parent)
|
||||
|
||||
void LLFloaterStats::addStatView(LLStatView* stat)
|
||||
{
|
||||
mStatsContainer->addChildAtEnd(stat);
|
||||
mStatsContainer->addChildInBack(stat);
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
||||
@@ -51,7 +51,7 @@
|
||||
#include "llpanelcontents.h"
|
||||
#include "llpanelface.h"
|
||||
#include "llpanelland.h"
|
||||
#include "llpanelinventory.h"
|
||||
#include "llpanelobjectinventory.h"
|
||||
#include "llpanelobject.h"
|
||||
#include "llpanelvolume.h"
|
||||
#include "llpanelpermissions.h"
|
||||
@@ -168,7 +168,7 @@ void* LLFloaterTools::createPanelContents(void* data)
|
||||
void* LLFloaterTools::createPanelContentsInventory(void* data)
|
||||
{
|
||||
LLFloaterTools* floater = (LLFloaterTools*)data;
|
||||
floater->mPanelContents->mPanelInventory = new LLPanelInventory(std::string("ContentsInventory"), LLRect());
|
||||
floater->mPanelContents->mPanelInventory = new LLPanelObjectInventory(std::string("ContentsInventory"), LLRect());
|
||||
return floater->mPanelContents->mPanelInventory;
|
||||
}
|
||||
|
||||
@@ -180,8 +180,41 @@ void* LLFloaterTools::createPanelLandInfo(void* data)
|
||||
return floater->mPanelLandInfo;
|
||||
}
|
||||
|
||||
static const std::string toolNames[]={
|
||||
"ToolCube",
|
||||
"ToolPrism",
|
||||
"ToolPyramid",
|
||||
"ToolTetrahedron",
|
||||
"ToolCylinder",
|
||||
"ToolHemiCylinder",
|
||||
"ToolCone",
|
||||
"ToolHemiCone",
|
||||
"ToolSphere",
|
||||
"ToolHemiSphere",
|
||||
"ToolTorus",
|
||||
"ToolTube",
|
||||
"ToolRing",
|
||||
"ToolTree",
|
||||
"ToolGrass"};
|
||||
LLPCode toolData[]={
|
||||
LL_PCODE_CUBE,
|
||||
LL_PCODE_PRISM,
|
||||
LL_PCODE_PYRAMID,
|
||||
LL_PCODE_TETRAHEDRON,
|
||||
LL_PCODE_CYLINDER,
|
||||
LL_PCODE_CYLINDER_HEMI,
|
||||
LL_PCODE_CONE,
|
||||
LL_PCODE_CONE_HEMI,
|
||||
LL_PCODE_SPHERE,
|
||||
LL_PCODE_SPHERE_HEMI,
|
||||
LL_PCODE_TORUS,
|
||||
LLViewerObject::LL_VO_SQUARE_TORUS,
|
||||
LLViewerObject::LL_VO_TRIANGLE_TORUS,
|
||||
LL_PCODE_LEGACY_TREE,
|
||||
LL_PCODE_LEGACY_GRASS};
|
||||
|
||||
BOOL LLFloaterTools::postBuild()
|
||||
{
|
||||
{
|
||||
|
||||
// Hide until tool selected
|
||||
setVisible(FALSE);
|
||||
@@ -250,44 +283,12 @@ BOOL LLFloaterTools::postBuild()
|
||||
// Create Buttons
|
||||
//
|
||||
|
||||
static const std::string toolNames[]={
|
||||
"ToolCube",
|
||||
"ToolPrism",
|
||||
"ToolPyramid",
|
||||
"ToolTetrahedron",
|
||||
"ToolCylinder",
|
||||
"ToolHemiCylinder",
|
||||
"ToolCone",
|
||||
"ToolHemiCone",
|
||||
"ToolSphere",
|
||||
"ToolHemiSphere",
|
||||
"ToolTorus",
|
||||
"ToolTube",
|
||||
"ToolRing",
|
||||
"ToolTree",
|
||||
"ToolGrass"};
|
||||
void* toolData[]={
|
||||
&LLToolPlacerPanel::sCube,
|
||||
&LLToolPlacerPanel::sPrism,
|
||||
&LLToolPlacerPanel::sPyramid,
|
||||
&LLToolPlacerPanel::sTetrahedron,
|
||||
&LLToolPlacerPanel::sCylinder,
|
||||
&LLToolPlacerPanel::sCylinderHemi,
|
||||
&LLToolPlacerPanel::sCone,
|
||||
&LLToolPlacerPanel::sConeHemi,
|
||||
&LLToolPlacerPanel::sSphere,
|
||||
&LLToolPlacerPanel::sSphereHemi,
|
||||
&LLToolPlacerPanel::sTorus,
|
||||
&LLToolPlacerPanel::sSquareTorus,
|
||||
&LLToolPlacerPanel::sTriangleTorus,
|
||||
&LLToolPlacerPanel::sTree,
|
||||
&LLToolPlacerPanel::sGrass};
|
||||
for(size_t t=0; t<LL_ARRAY_SIZE(toolNames); ++t)
|
||||
{
|
||||
LLButton *found = getChild<LLButton>(toolNames[t]);
|
||||
if(found)
|
||||
{
|
||||
found->setClickedCallback(setObjectType,toolData[t]);
|
||||
found->setClickedCallback(boost::bind(&LLFloaterTools::setObjectType, toolData[t]));
|
||||
mButtons.push_back( found );
|
||||
}
|
||||
else
|
||||
@@ -737,15 +738,13 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
|
||||
else
|
||||
{
|
||||
// Highlight the correct placer button
|
||||
for( std::vector<LLButton*>::size_type i = 0; i < mButtons.size(); i++ )
|
||||
for( S32 t = 0; t < (S32)mButtons.size(); t++ )
|
||||
{
|
||||
LLPCode pcode = LLToolPlacer::getObjectType();
|
||||
void *userdata = mButtons[i]->getCallbackUserData();
|
||||
LLPCode *cur = (LLPCode*) userdata;
|
||||
|
||||
BOOL state = (pcode == *cur);
|
||||
mButtons[i]->setToggleState( state );
|
||||
mButtons[i]->setVisible( create_visible );
|
||||
LLPCode button_pcode = toolData[t];
|
||||
BOOL state = (pcode == button_pcode);
|
||||
mButtons[t]->setToggleState( state );
|
||||
mButtons[t]->setVisible( create_visible );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1034,9 +1033,8 @@ void commit_grid_mode(LLUICtrl *ctrl, void *data)
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterTools::setObjectType( void* data )
|
||||
void LLFloaterTools::setObjectType( LLPCode pcode )
|
||||
{
|
||||
LLPCode pcode = *(LLPCode*) data;
|
||||
LLToolPlacer::setObjectType( pcode );
|
||||
gSavedSettings.setBOOL("CreateToolCopySelection", FALSE);
|
||||
gFocusMgr.setMouseCapture(NULL);
|
||||
@@ -1067,11 +1065,11 @@ void LLFloaterTools::onSelectTreesGrass(LLUICtrl*, void*)
|
||||
{
|
||||
const std::string &selected = gFloaterTools->mComboTreesGrass->getValue();
|
||||
LLPCode pcode = LLToolPlacer::getObjectType();
|
||||
if (pcode == LLToolPlacerPanel::sTree)
|
||||
if (pcode == LL_PCODE_LEGACY_TREE)
|
||||
{
|
||||
gSavedSettings.setString("LastTree", selected);
|
||||
}
|
||||
else if (pcode == LLToolPlacerPanel::sGrass)
|
||||
else if (pcode == LL_PCODE_LEGACY_GRASS)
|
||||
{
|
||||
gSavedSettings.setString("LastGrass", selected);
|
||||
}
|
||||
@@ -1085,7 +1083,7 @@ void LLFloaterTools::updateTreeGrassCombo(bool visible)
|
||||
LLPCode pcode = LLToolPlacer::getObjectType();
|
||||
std::map<std::string, S32>::iterator it, end;
|
||||
std::string selected;
|
||||
if (pcode == LLToolPlacerPanel::sTree)
|
||||
if (pcode == LL_PCODE_LEGACY_TREE)
|
||||
{
|
||||
tree_grass_label->setVisible(visible);
|
||||
LLButton* button = getChild<LLButton>("ToolTree");
|
||||
@@ -1095,7 +1093,7 @@ void LLFloaterTools::updateTreeGrassCombo(bool visible)
|
||||
it = LLVOTree::sSpeciesNames.begin();
|
||||
end = LLVOTree::sSpeciesNames.end();
|
||||
}
|
||||
else if (pcode == LLToolPlacerPanel::sGrass)
|
||||
else if (pcode == LL_PCODE_LEGACY_GRASS)
|
||||
{
|
||||
tree_grass_label->setVisible(visible);
|
||||
LLButton* button = getChild<LLButton>("ToolGrass");
|
||||
|
||||
@@ -103,10 +103,10 @@ public:
|
||||
static void setEditTool(void* data);
|
||||
void saveLastTool();
|
||||
private:
|
||||
static void setObjectType( void* data );
|
||||
|
||||
|
||||
void refresh();
|
||||
|
||||
static void setObjectType( LLPCode pcode );
|
||||
static void onClickGridOptions(void* data);
|
||||
|
||||
public:
|
||||
|
||||
@@ -208,13 +208,9 @@ BOOL LLFloaterWorldMap::postBuild()
|
||||
|
||||
childSetAction("DoSearch", onLocationCommit, this);
|
||||
|
||||
childSetFocusChangedCallback("location", onLocationFocusChanged, this);
|
||||
|
||||
LLLineEditor *location_editor = getChild<LLLineEditor>("location");
|
||||
if (location_editor)
|
||||
{
|
||||
location_editor->setKeystrokeCallback( onSearchTextEntry );
|
||||
}
|
||||
location_editor->setFocusChangedCallback(boost::bind(&LLFloaterWorldMap::onLocationFocusChanged, this, _1));
|
||||
location_editor->setKeystrokeCallback( onSearchTextEntry );
|
||||
|
||||
childSetCommitCallback("search_results", onCommitSearchResult, this);
|
||||
childSetDoubleClickCallback("search_results", onClickTeleportBtn);
|
||||
@@ -1132,7 +1128,7 @@ void LLFloaterWorldMap::onComboTextEntry( LLLineEditor* ctrl, void* userdata )
|
||||
void LLFloaterWorldMap::onSearchTextEntry( LLLineEditor* ctrl, void* userdata )
|
||||
{
|
||||
onComboTextEntry(ctrl, userdata);
|
||||
updateSearchEnabled(ctrl, userdata);
|
||||
gFloaterWorldMap->updateSearchEnabled();
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -1239,24 +1235,21 @@ void LLFloaterWorldMap::onAvatarComboCommit( LLUICtrl* ctrl, void* userdata )
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFloaterWorldMap::onLocationFocusChanged( LLFocusableElement* focus, void* userdata )
|
||||
void LLFloaterWorldMap::onLocationFocusChanged( LLFocusableElement* focus )
|
||||
{
|
||||
updateSearchEnabled((LLUICtrl*)focus, userdata);
|
||||
updateSearchEnabled();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterWorldMap::updateSearchEnabled( LLUICtrl* ctrl, void* userdata )
|
||||
void LLFloaterWorldMap::updateSearchEnabled()
|
||||
{
|
||||
LLFloaterWorldMap *self = gFloaterWorldMap;
|
||||
if (self->childHasKeyboardFocus("location") &&
|
||||
self->childGetValue("location").asString().length() > 0)
|
||||
if (childHasKeyboardFocus("location") &&
|
||||
childGetValue("location").asString().length() > 0)
|
||||
{
|
||||
self->setDefaultBtn("DoSearch");
|
||||
setDefaultBtn("DoSearch");
|
||||
}
|
||||
else
|
||||
{
|
||||
self->setDefaultBtn(NULL);
|
||||
setDefaultBtn(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -151,8 +151,8 @@ protected:
|
||||
void flyToAvatar();
|
||||
void teleportToAvatar();
|
||||
|
||||
static void updateSearchEnabled( LLUICtrl* ctrl, void* userdata );
|
||||
static void onLocationFocusChanged( LLFocusableElement* ctrl, void* userdata );
|
||||
void updateSearchEnabled();
|
||||
void onLocationFocusChanged( LLFocusableElement* focus );
|
||||
static void onLocationCommit( void* userdata );
|
||||
static void onCommitLocation( LLUICtrl* ctrl, void* userdata );
|
||||
static void onCommitSearchResult( LLUICtrl* ctrl, void* userdata );
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -71,18 +71,14 @@ class LLTextBox;
|
||||
// manages the screen region of the folder view.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class LLUICtrl;
|
||||
class LLLineEditor;
|
||||
|
||||
class LLFolderView : public LLFolderViewFolder, LLEditMenuHandler
|
||||
class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
|
||||
{
|
||||
public:
|
||||
typedef void (*SelectCallback)(const std::deque<LLFolderViewItem*> &items, BOOL user_action, void* data);
|
||||
|
||||
static F32 sAutoOpenTime;
|
||||
|
||||
LLFolderView( const std::string& name, LLUIImagePtr root_folder_icon, const LLRect& rect,
|
||||
const LLUUID& source_id, LLView *parent_view );
|
||||
LLFolderView( const std::string& name, const LLRect& rect,
|
||||
const LLUUID& source_id, LLPanel *parent_view, LLFolderViewEventListener* listener );
|
||||
virtual ~LLFolderView( void );
|
||||
|
||||
virtual BOOL canFocusChildren() const;
|
||||
@@ -92,28 +88,31 @@ public:
|
||||
// FolderViews default to sort by name. This will change that,
|
||||
// and resort the items if necessary.
|
||||
void setSortOrder(U32 order);
|
||||
void checkTreeResortForModelChanged();
|
||||
void setFilterPermMask(PermissionMask filter_perm_mask);
|
||||
void setSelectCallback(SelectCallback callback, void* user_data) { mSelectCallback = callback, mUserData = user_data; }
|
||||
|
||||
typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
|
||||
void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
|
||||
void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
|
||||
void setAllowMultiSelect(BOOL allow) { mAllowMultiSelect = allow; }
|
||||
|
||||
LLInventoryFilter* getFilter();
|
||||
const std::string getFilterSubString(BOOL trim = FALSE);
|
||||
bool getFilterWorn() const;
|
||||
U32 getFilterTypes() const;
|
||||
U32 getFilterObjectTypes() const;
|
||||
PermissionMask getFilterPermissions() const;
|
||||
// *NOTE: use getFilter()->getShowFolderState();
|
||||
//LLInventoryFilter::EFolderShow getShowFolderState();
|
||||
U32 getSortOrder() const;
|
||||
BOOL isFilterModified();
|
||||
BOOL getAllowMultiSelect() { return mAllowMultiSelect; }
|
||||
|
||||
bool getAllowMultiSelect() { return mAllowMultiSelect; }
|
||||
|
||||
U32 toggleSearchType(std::string toggle);
|
||||
U32 getSearchType() const;
|
||||
|
||||
// Close all folders in the view
|
||||
void closeAllFolders();
|
||||
void openFolder(const std::string& foldername);
|
||||
void openTopLevelFolders();
|
||||
|
||||
virtual void toggleOpen() {};
|
||||
virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse);
|
||||
@@ -136,13 +135,17 @@ public:
|
||||
virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
|
||||
BOOL take_keyboard_focus);
|
||||
|
||||
// Used by menu callbacks
|
||||
void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
|
||||
|
||||
// Called once a frame to update the selection if mSelectThisID has been set
|
||||
void updateSelection();
|
||||
|
||||
// This method is used to toggle the selection of an item. Walks
|
||||
// children, and keeps track of selected objects.
|
||||
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
|
||||
|
||||
virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items);
|
||||
|
||||
virtual BOOL getSelectionList(std::set<LLUUID> &selection);
|
||||
virtual std::set<LLUUID> getSelectionList() const;
|
||||
|
||||
// make sure if ancestor is selected, descendents are not
|
||||
void sanitizeSelection();
|
||||
@@ -152,6 +155,8 @@ public:
|
||||
|
||||
BOOL startDrag(LLToolDragAndDrop::ESource source);
|
||||
void setDragAndDropThisFrame() { mDragAndDropThisFrame = TRUE; }
|
||||
void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; }
|
||||
LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; }
|
||||
|
||||
// deletion functionality
|
||||
void removeSelectedItems();
|
||||
@@ -160,6 +165,9 @@ public:
|
||||
void openSelectedItems( void );
|
||||
void propertiesSelectedItems( void );
|
||||
|
||||
// change the folder type
|
||||
void changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type);
|
||||
|
||||
void autoOpenItem(LLFolderViewFolder* item);
|
||||
void closeAutoOpenedFolders();
|
||||
BOOL autoOpenTest(LLFolderViewFolder* item);
|
||||
@@ -188,9 +196,6 @@ public:
|
||||
//void dragItemIntoFolder( LLFolderViewItem* moving_item, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
|
||||
//void dragFolderIntoFolder( LLFolderViewFolder* moving_folder, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
|
||||
|
||||
// LLUICtrl Functionality
|
||||
/*virtual*/ void setFocus(BOOL focus);
|
||||
|
||||
// LLView functionality
|
||||
///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
|
||||
/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
|
||||
@@ -205,13 +210,12 @@ public:
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
|
||||
/*virtual*/ void onFocusLost();
|
||||
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
|
||||
virtual void draw();
|
||||
virtual void deleteAllChildren();
|
||||
|
||||
void scrollToShowSelection();
|
||||
void scrollToShowItem(LLFolderViewItem* item);
|
||||
void scrollToShowItem(LLFolderViewItem* item, const LLRect& constraint_rect);
|
||||
void setScrollContainer( LLScrollableContainerView* parent ) { mScrollContainer = parent; }
|
||||
LLRect getVisibleRect();
|
||||
|
||||
@@ -221,10 +225,12 @@ public:
|
||||
void setShowSingleSelection(BOOL show);
|
||||
BOOL getShowSingleSelection() { return mShowSingleSelection; }
|
||||
F32 getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
|
||||
bool getUseEllipses() { return mUseEllipses; }
|
||||
|
||||
void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
|
||||
void removeItemID(const LLUUID& id);
|
||||
LLFolderViewItem* getItemByID(const LLUUID& id);
|
||||
LLFolderViewFolder* getFolderByID(const LLUUID& id);
|
||||
|
||||
void doIdle(); // Real idle routine
|
||||
static void idle(void* user_data); // static glue to doIdle()
|
||||
@@ -232,21 +238,37 @@ public:
|
||||
BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }
|
||||
BOOL needsAutoRename() { return mNeedsAutoRename; }
|
||||
void setNeedsAutoRename(BOOL val) { mNeedsAutoRename = val; }
|
||||
void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
|
||||
void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; }
|
||||
|
||||
BOOL getDebugFilters() { return mDebugFilters; }
|
||||
|
||||
LLPanel* getParentPanel() { return mParentPanel; }
|
||||
// DEBUG only
|
||||
void dumpSelectionInformation();
|
||||
|
||||
virtual S32 notify(const LLSD& info) ;
|
||||
|
||||
bool useLabelSuffix() { return mUseLabelSuffix; }
|
||||
void updateMenu();
|
||||
|
||||
private:
|
||||
void updateMenuOptions(LLMenuGL* menu);
|
||||
void updateRenamerPosition();
|
||||
|
||||
protected:
|
||||
LLScrollableContainerView* mScrollContainer; // NULL if this is not a child of a scroll container.
|
||||
|
||||
static void commitRename( LLUICtrl* renamer, void* user_data );
|
||||
static void onRenamerLost( LLUICtrl* renamer, void* user_data);
|
||||
void onRenamerLost();
|
||||
|
||||
void finishRenamingItem( void );
|
||||
void closeRenamer( void );
|
||||
|
||||
bool selectFirstItem();
|
||||
bool selectLastItem();
|
||||
|
||||
BOOL addNoOptions(LLMenuGL* menu) const;
|
||||
protected:
|
||||
LLHandle<LLView> mPopupMenuHandle;
|
||||
|
||||
@@ -254,6 +276,7 @@ protected:
|
||||
selected_items_t mSelectedItems;
|
||||
BOOL mKeyboardSelection;
|
||||
BOOL mAllowMultiSelect;
|
||||
BOOL mShowEmptyMessage;
|
||||
BOOL mShowFolderHierarchy;
|
||||
LLUUID mSourceID;
|
||||
|
||||
@@ -262,11 +285,12 @@ protected:
|
||||
LLLineEditor* mRenamer;
|
||||
|
||||
BOOL mNeedsScroll;
|
||||
LLFolderViewItem* mLastScrollItem;
|
||||
LLCoordGL mLastScrollOffset;
|
||||
BOOL mPinningSelectedItem;
|
||||
LLRect mScrollConstraintRect;
|
||||
BOOL mNeedsAutoSelect;
|
||||
BOOL mAutoSelectOverride;
|
||||
BOOL mNeedsAutoRename;
|
||||
bool mUseLabelSuffix;
|
||||
|
||||
BOOL mDebugFilters;
|
||||
U32 mSortOrder;
|
||||
@@ -282,12 +306,32 @@ protected:
|
||||
LLFrameTimer mMultiSelectionFadeTimer;
|
||||
S32 mArrangeGeneration;
|
||||
|
||||
void* mUserData;
|
||||
SelectCallback mSelectCallback;
|
||||
signal_t mSelectSignal;
|
||||
signal_t mReshapeSignal;
|
||||
S32 mSignalSelectCallback;
|
||||
S32 mMinWidth;
|
||||
S32 mRunningHeight;
|
||||
std::map<LLUUID, LLFolderViewItem*> mItemMap;
|
||||
BOOL mDragAndDropThisFrame;
|
||||
|
||||
LLUUID mSelectThisID; // if non null, select this item
|
||||
|
||||
LLPanel* mParentPanel;
|
||||
|
||||
/**
|
||||
* Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
|
||||
* NOTE: For now it uses only to cut LLFolderViewItem::mLabel text to be used for Landmarks in Places Panel.
|
||||
*/
|
||||
bool mUseEllipses; // See EXT-719
|
||||
|
||||
/**
|
||||
* Contains item under mouse pointer while dragging
|
||||
*/
|
||||
LLFolderViewItem* mDraggingOverItem; // See EXT-719
|
||||
|
||||
public:
|
||||
static F32 sAutoOpenTime;
|
||||
LLTextBox* mStatusTextBox;
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -55,23 +55,27 @@ public:
|
||||
virtual const LLUUID& getUUID() const = 0;
|
||||
virtual time_t getCreationDate() const = 0; // UTC seconds
|
||||
virtual PermissionMask getPermissionMask() const = 0;
|
||||
virtual LLFolderType::EType getPreferredType() const = 0;
|
||||
virtual LLPointer<LLUIImage> getIcon() const = 0;
|
||||
virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
|
||||
virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
|
||||
virtual std::string getLabelSuffix() const = 0;
|
||||
virtual void openItem( void ) = 0;
|
||||
virtual void closeItem( void ) = 0;
|
||||
virtual void previewItem( void ) = 0;
|
||||
virtual void selectItem(void) = 0;
|
||||
virtual void showProperties(void) = 0;
|
||||
virtual BOOL isItemRenameable() const = 0;
|
||||
virtual BOOL renameItem(const std::string& new_name) = 0;
|
||||
virtual BOOL isItemMovable( void ) = 0; // Can be moved to another folder
|
||||
virtual BOOL isItemRemovable( void ) = 0; // Can be destroyed
|
||||
virtual BOOL isItemMovable( void ) const = 0; // Can be moved to another folder
|
||||
virtual BOOL isItemRemovable( void ) const = 0; // Can be destroyed
|
||||
virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.
|
||||
virtual BOOL removeItem() = 0;
|
||||
virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0;
|
||||
virtual void move( LLFolderViewEventListener* parent_listener ) = 0;
|
||||
virtual BOOL isItemCopyable() const = 0;
|
||||
virtual BOOL copyToClipboard() const = 0;
|
||||
virtual BOOL cutToClipboard() const = 0;
|
||||
virtual void cutToClipboard() = 0;
|
||||
virtual BOOL isClipboardPasteable() const = 0;
|
||||
virtual void pasteFromClipboard() = 0;
|
||||
virtual void pasteLinkFromClipboard() = 0;
|
||||
@@ -79,12 +83,13 @@ public:
|
||||
virtual BOOL isUpToDate() const = 0;
|
||||
virtual BOOL hasChildren() const = 0;
|
||||
virtual LLInventoryType::EType getInventoryType() const = 0;
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action) {}
|
||||
|
||||
virtual void performAction(LLInventoryModel* model, std::string action) = 0;
|
||||
virtual LLWearableType::EType getWearableType() const = 0;
|
||||
|
||||
// This method should be called when a drag begins. returns TRUE
|
||||
// if the drag can begin, otherwise FALSE.
|
||||
virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
|
||||
|
||||
|
||||
// This method will be called to determine if a drop can be
|
||||
// performed, and will set drop to TRUE if a drop is
|
||||
// requested. Returns TRUE if a drop is possible/happened,
|
||||
@@ -92,17 +97,6 @@ public:
|
||||
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data) = 0;
|
||||
|
||||
// This method is called when the object being referenced by the
|
||||
// bridge is actually dropped. This allows for cleanup of the old
|
||||
// view, reference counting, etc.
|
||||
// virtual void dropped() = 0;
|
||||
|
||||
// this method accesses the parent and arranges and sets it as
|
||||
// specified.
|
||||
void arrangeAndSet(LLFolderViewItem* focus, BOOL set_selection,
|
||||
BOOL take_keyboard_focus = TRUE);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -60,10 +60,10 @@ class LLInventorySort
|
||||
public:
|
||||
LLInventorySort()
|
||||
: mSortOrder(0),
|
||||
mByDate(false),
|
||||
mSystemToTop(false),
|
||||
mFoldersByName(false) { }
|
||||
|
||||
mByDate(false),
|
||||
mSystemToTop(false),
|
||||
mFoldersByName(false) { }
|
||||
|
||||
// Returns true if order has changed
|
||||
bool updateSort(U32 order);
|
||||
U32 getSort() { return mSortOrder; }
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
friend class LLFolderViewEventListener;
|
||||
|
||||
static const S32 LEFT_PAD = 5;
|
||||
static const S32 LEFT_INDENTATION = 13;
|
||||
static const S32 LEFT_INDENTATION = 6;
|
||||
static const S32 ICON_PAD = 2;
|
||||
static const S32 ICON_WIDTH = 16;
|
||||
static const S32 TEXT_PAD = 1;
|
||||
@@ -101,19 +101,13 @@ public:
|
||||
// animation parameters
|
||||
static const F32 FOLDER_CLOSE_TIME_CONSTANT;
|
||||
static const F32 FOLDER_OPEN_TIME_CONSTANT;
|
||||
|
||||
BOOL isLoading() const { return mIsLoading; }
|
||||
|
||||
private:
|
||||
BOOL mIsSelected;
|
||||
|
||||
protected:
|
||||
static const LLFontGL* sFont;
|
||||
static const LLFontGL* sSmallFont;
|
||||
static LLColor4 sFgColor;
|
||||
static LLColor4 sHighlightBgColor;
|
||||
static LLColor4 sHighlightFgColor;
|
||||
static LLColor4 sFilterBGColor;
|
||||
static LLColor4 sFilterTextColor;
|
||||
static LLColor4 sSuffixColor;
|
||||
static LLColor4 sSearchStatusColor;
|
||||
static LLUIImagePtr sArrowImage;
|
||||
static LLUIImagePtr sBoxImage;
|
||||
|
||||
@@ -121,10 +115,9 @@ protected:
|
||||
std::string mSearchableLabel;
|
||||
std::string mSearchableLabelDesc;
|
||||
std::string mSearchableLabelCreator;
|
||||
std::string mSearchable;
|
||||
std::string mType;
|
||||
S32 mLabelWidth;
|
||||
U32 mCreationDate;
|
||||
bool mLabelWidthDirty;
|
||||
time_t mCreationDate;
|
||||
LLFolderViewFolder* mParentFolder;
|
||||
LLFolderViewEventListener* mListener;
|
||||
BOOL mIsCurSelection;
|
||||
@@ -133,8 +126,11 @@ protected:
|
||||
std::string mLabelSuffix;
|
||||
LLUIImagePtr mIcon;
|
||||
std::string mStatusText;
|
||||
LLUIImagePtr mIconOpen;
|
||||
LLUIImagePtr mIconOverlay;
|
||||
BOOL mHasVisibleChildren;
|
||||
S32 mIndentation;
|
||||
S32 mItemHeight;
|
||||
BOOL mPassedFilter;
|
||||
S32 mLastFilterGeneration;
|
||||
std::string::size_type mStringMatchOffset;
|
||||
@@ -143,19 +139,31 @@ protected:
|
||||
BOOL mDragAndDropTarget;
|
||||
BOOL mIsLoading;
|
||||
LLTimer mTimeSinceRequestStart;
|
||||
bool mShowLoadStatus;
|
||||
|
||||
std::string mSearchable;
|
||||
U32 mSearchType;
|
||||
|
||||
// helper function to change the selection from the root.
|
||||
void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
|
||||
|
||||
// helper function to change the selection from the root.
|
||||
void extendSelectionFromRoot(LLFolderViewItem* selection);
|
||||
//Sets extra search criteria 'labels' to be compared against by filter.
|
||||
void updateExtraSearchCriteria();
|
||||
//Update mSearchable string based on roots search flags. (Name, creator, desc)
|
||||
void updateSearchLabelType();
|
||||
|
||||
// this is an internal method used for adding items to folders. A
|
||||
// no-op at this leve, but reimplemented in derived classes.
|
||||
// no-op at this level, but reimplemented in derived classes.
|
||||
virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
|
||||
virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
|
||||
|
||||
static LLFontGL* getLabelFontForStyle(U8 style);
|
||||
|
||||
virtual void setCreationDate(time_t creation_date_utc) { mCreationDate = creation_date_utc; }
|
||||
|
||||
public:
|
||||
BOOL postBuild();
|
||||
|
||||
// This function clears the currently selected item, and records
|
||||
// the specified selected item appropriately for display and use
|
||||
// in the UI. If open is TRUE, then folders are opened up along
|
||||
@@ -163,16 +171,16 @@ public:
|
||||
void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem,
|
||||
BOOL take_keyboard_focus = TRUE);
|
||||
|
||||
|
||||
|
||||
// This function is called when the folder view is dirty. It's
|
||||
// implemented here but called by derived classes when folding the
|
||||
// views.
|
||||
void arrangeFromRoot();
|
||||
void filterFromRoot( void );
|
||||
|
||||
void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus);
|
||||
|
||||
// creation_date is in UTC seconds
|
||||
LLFolderViewItem( const std::string& name, LLUIImagePtr icon, S32 creation_date, LLFolderView* root, LLFolderViewEventListener* listener );
|
||||
LLFolderViewItem( const std::string& name, LLUIImagePtr icon, LLUIImagePtr icon_open, LLUIImagePtr icon_overlay, S32 creation_date, LLFolderView* root, LLFolderViewEventListener* listener );
|
||||
virtual ~LLFolderViewItem( void );
|
||||
|
||||
// addToFolder() returns TRUE if it succeeds. FALSE otherwise
|
||||
@@ -203,9 +211,6 @@ public:
|
||||
// Returns TRUE if the selection state of this item was changed.
|
||||
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
|
||||
|
||||
// this method is used to group select items
|
||||
virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items) { }
|
||||
|
||||
// this method is used to deselect this element
|
||||
void deselectItem();
|
||||
|
||||
@@ -213,7 +218,7 @@ public:
|
||||
virtual void selectItem();
|
||||
|
||||
// gets multiple-element selection
|
||||
virtual BOOL getSelectionList(std::set<LLUUID> &selection){return TRUE;}
|
||||
virtual std::set<LLUUID> getSelectionList() const;
|
||||
|
||||
// Returns true is this object and all of its children can be removed (deleted by user)
|
||||
virtual BOOL isRemovable();
|
||||
@@ -226,12 +231,16 @@ public:
|
||||
|
||||
BOOL isSelected() const { return mIsSelected; }
|
||||
|
||||
void setUnselected() { mIsSelected = FALSE; }
|
||||
|
||||
void setIsCurSelection(BOOL select) { mIsCurSelection = select; }
|
||||
|
||||
BOOL getIsCurSelection() { return mIsCurSelection; }
|
||||
|
||||
BOOL hasVisibleChildren() { return mHasVisibleChildren; }
|
||||
|
||||
void setShowLoadStatus(bool status) { mShowLoadStatus = status; }
|
||||
|
||||
// Call through to the viewed object and return true if it can be
|
||||
// removed. Returns true if it's removed.
|
||||
//virtual BOOL removeRecursively(BOOL single_item);
|
||||
@@ -244,7 +253,7 @@ public:
|
||||
// viewed. This method will ask the viewed object itself.
|
||||
const std::string& getName( void ) const;
|
||||
|
||||
std::string& getSearchableLabel( void );
|
||||
const std::string& getSearchableLabel( void );
|
||||
|
||||
// This method returns the label displayed on the view. This
|
||||
// method was primarily added to allow sorting on the folder
|
||||
@@ -253,10 +262,10 @@ public:
|
||||
|
||||
// Used for sorting, like getLabel() above.
|
||||
virtual time_t getCreationDate() const { return mCreationDate; }
|
||||
|
||||
|
||||
LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
|
||||
const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
|
||||
|
||||
|
||||
LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
|
||||
LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
|
||||
|
||||
@@ -276,7 +285,7 @@ public:
|
||||
// Show children (unfortunate that this is called "open")
|
||||
virtual void setOpen(BOOL open = TRUE) {};
|
||||
|
||||
virtual BOOL isOpen() { return FALSE; }
|
||||
virtual BOOL isOpen() const { return FALSE; }
|
||||
|
||||
virtual LLFolderView* getRoot();
|
||||
BOOL isDescendantOf( const LLFolderViewFolder* potential_ancestor );
|
||||
@@ -305,13 +314,24 @@ public:
|
||||
virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
|
||||
virtual BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
|
||||
|
||||
virtual LLView* getChildView(const std::string& name, BOOL recurse, BOOL create_if_missing) const
|
||||
{
|
||||
if(create_if_missing)
|
||||
return LLView::getChildView(name, recurse, TRUE);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// virtual void handleDropped();
|
||||
virtual void draw();
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
|
||||
private:
|
||||
static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
|
||||
};
|
||||
|
||||
|
||||
@@ -331,11 +351,13 @@ class LLFolderViewFolder : public LLFolderViewItem
|
||||
{
|
||||
protected:
|
||||
LLFolderViewFolder( const std::string& name, LLUIImagePtr icon,
|
||||
LLUIImagePtr icon_open,
|
||||
LLUIImagePtr icon_link,
|
||||
LLFolderView* root,
|
||||
LLFolderViewEventListener* listener );
|
||||
|
||||
friend class LLBuildNewViewsScheduler;
|
||||
friend class LLPanelInventory;
|
||||
friend class LLPanelObjectInventory;
|
||||
friend class LLInventoryPanel;
|
||||
|
||||
public:
|
||||
@@ -347,13 +369,6 @@ public:
|
||||
typedef std::list<LLFolderViewItem*> items_t;
|
||||
typedef std::list<LLFolderViewFolder*> folders_t;
|
||||
|
||||
private:
|
||||
S32 mNumDescendantsSelected;
|
||||
|
||||
public: // Accessed needed by LLFolderViewItem
|
||||
void recursiveIncrementNumDescendantsSelected(S32 increment);
|
||||
S32 numSelected(void) const { return mNumDescendantsSelected + (isSelected() ? 1 : 0); }
|
||||
|
||||
protected:
|
||||
items_t mItems;
|
||||
folders_t mFolders;
|
||||
@@ -370,6 +385,9 @@ protected:
|
||||
S32 mLastCalculatedWidth;
|
||||
S32 mCompletedFilterGeneration;
|
||||
S32 mMostFilteredDescendantGeneration;
|
||||
bool mNeedsSort;
|
||||
bool mPassedFolderFilter;
|
||||
|
||||
public:
|
||||
typedef enum e_recurse_type
|
||||
{
|
||||
@@ -395,6 +413,7 @@ public:
|
||||
virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
|
||||
|
||||
BOOL needsArrange();
|
||||
void requestSort();
|
||||
|
||||
// Returns the sort group (system, trash, folder) for this folder.
|
||||
virtual EInventorySortGroup getSortGroup() const;
|
||||
@@ -402,13 +421,21 @@ public:
|
||||
virtual void setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
|
||||
virtual S32 getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
|
||||
|
||||
BOOL hasFilteredDescendants(S32 filter_generation) { return mMostFilteredDescendantGeneration >= filter_generation; }
|
||||
BOOL hasFilteredDescendants(S32 filter_generation);
|
||||
BOOL hasFilteredDescendants();
|
||||
|
||||
// applies filters to control visibility of inventory items
|
||||
virtual void filter( LLInventoryFilter& filter);
|
||||
virtual void setFiltered(BOOL filtered, S32 filter_generation);
|
||||
virtual BOOL getFiltered();
|
||||
virtual BOOL getFiltered(S32 filter_generation);
|
||||
|
||||
virtual void dirtyFilter();
|
||||
|
||||
// folder-specific filtering (filter status propagates top down instead of bottom up)
|
||||
void filterFolder(LLInventoryFilter& filter);
|
||||
void setFilteredFolder(bool filtered, S32 filter_generation);
|
||||
bool getFilteredFolder(S32 filter_generation);
|
||||
|
||||
// Passes selection information on to children and record
|
||||
// selection information if necessary.
|
||||
@@ -423,10 +450,7 @@ public:
|
||||
virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
|
||||
|
||||
// this method is used to group select items
|
||||
virtual void extendSelection(LLFolderViewItem* selection, LLFolderViewItem* last_selected, LLDynamicArray<LLFolderViewItem*>& items);
|
||||
|
||||
// Deselect this folder and all folder/items it contains recursively.
|
||||
void recursiveDeselect(BOOL deselect_self);
|
||||
void extendSelectionTo(LLFolderViewItem* selection);
|
||||
|
||||
// Returns true is this object and all of its children can be removed.
|
||||
virtual BOOL isRemovable();
|
||||
@@ -482,21 +506,24 @@ public:
|
||||
virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse = RECURSE_NO);
|
||||
|
||||
// Get the current state of the folder.
|
||||
virtual BOOL isOpen() { return mIsOpen; }
|
||||
virtual BOOL isOpen() const { return mIsOpen; }
|
||||
|
||||
// special case if an object is dropped on the child.
|
||||
BOOL handleDragAndDropFromChild(MASK mask,
|
||||
BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
|
||||
void applyFunctorRecursively(LLFolderViewFunctor& functor);
|
||||
virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
|
||||
|
||||
// Just apply this functor to the folder's immediate children.
|
||||
void applyFunctorToChildren(LLFolderViewFunctor& functor);
|
||||
|
||||
virtual void openItem( void );
|
||||
virtual BOOL addItem(LLFolderViewItem* item);
|
||||
virtual BOOL addItem(LLFolderViewItem* item);
|
||||
virtual BOOL addFolder( LLFolderViewFolder* folder);
|
||||
|
||||
// LLView functionality
|
||||
@@ -505,15 +532,19 @@ public:
|
||||
virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
|
||||
virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
|
||||
virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
virtual void draw();
|
||||
|
||||
time_t getCreationDate() const;
|
||||
bool isTrash() const;
|
||||
S32 getNumSelectedDescendants(void) const { return mNumDescendantsSelected; }
|
||||
|
||||
folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); }
|
||||
folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); }
|
||||
@@ -522,6 +553,8 @@ public:
|
||||
items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
|
||||
items_t::const_iterator getItemsEnd() const { return mItems.end(); }
|
||||
items_t::size_type getItemsCount() const { return mItems.size(); }
|
||||
LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
|
||||
void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items);
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llgesturemgr.cpp
|
||||
* @brief Manager for playing gestures on the viewer
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -37,11 +31,12 @@
|
||||
// system
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
#include <boost/tokenizer.hpp>
|
||||
|
||||
// library
|
||||
#include "llaudioengine.h"
|
||||
#include "lldatapacker.h"
|
||||
#include "llinventory.h"
|
||||
#include "llkeyframemotion.h"
|
||||
#include "llmultigesture.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llstl.h"
|
||||
@@ -53,10 +48,11 @@
|
||||
#include "llagent.h"
|
||||
#include "llchatbar.h"
|
||||
#include "lldelayedgestureerror.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llviewermessage.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llappearancemgr.h"
|
||||
|
||||
#include "chatbar_as_cmdline.h"
|
||||
|
||||
@@ -78,7 +74,9 @@ LLGestureMgr::LLGestureMgr()
|
||||
mPlaying(),
|
||||
mActive(),
|
||||
mLoadingCount(0)
|
||||
{ }
|
||||
{
|
||||
gInventory.addObserver(this);
|
||||
}
|
||||
|
||||
|
||||
// We own the data for gestures, so clean them up.
|
||||
@@ -92,6 +90,7 @@ LLGestureMgr::~LLGestureMgr()
|
||||
delete gesture;
|
||||
gesture = NULL;
|
||||
}
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
|
||||
|
||||
@@ -100,6 +99,41 @@ void LLGestureMgr::init()
|
||||
// TODO
|
||||
}
|
||||
|
||||
void LLGestureMgr::changed(U32 mask)
|
||||
{
|
||||
LLInventoryFetchItemsObserver::changed(mask);
|
||||
|
||||
if (mask & LLInventoryObserver::GESTURE)
|
||||
{
|
||||
// If there was a gesture label changed, update all the names in the
|
||||
// active gestures and then notify observers
|
||||
if (mask & LLInventoryObserver::LABEL)
|
||||
{
|
||||
for(item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it)
|
||||
{
|
||||
if(it->second)
|
||||
{
|
||||
LLViewerInventoryItem* item = gInventory.getItem(it->first);
|
||||
if(item)
|
||||
{
|
||||
it->second->mName = item->getName();
|
||||
}
|
||||
}
|
||||
}
|
||||
notifyObservers();
|
||||
}
|
||||
// If there was a gesture added or removed notify observers
|
||||
// STRUCTURE denotes that the inventory item has been moved
|
||||
// In the case of deleting gesture, it is moved to the trash
|
||||
else if(mask & LLInventoryObserver::ADD ||
|
||||
mask & LLInventoryObserver::REMOVE ||
|
||||
mask & LLInventoryObserver::STRUCTURE)
|
||||
{
|
||||
notifyObservers();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Use this version when you have the item_id but not the asset_id,
|
||||
// and you KNOW the inventory is loaded.
|
||||
@@ -307,6 +341,8 @@ void LLGestureMgr::deactivateGesture(const LLUUID& item_id)
|
||||
|
||||
gAgent.sendReliableMessage();
|
||||
|
||||
LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id, false);
|
||||
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
@@ -496,6 +532,66 @@ void LLGestureMgr::playGesture(LLMultiGesture* gesture)
|
||||
gesture->mPlaying = TRUE;
|
||||
mPlaying.push_back(gesture);
|
||||
|
||||
// Load all needed assets to minimize the delays
|
||||
// when gesture is playing.
|
||||
for (std::vector<LLGestureStep*>::iterator steps_it = gesture->mSteps.begin();
|
||||
steps_it != gesture->mSteps.end();
|
||||
++steps_it)
|
||||
{
|
||||
LLGestureStep* step = *steps_it;
|
||||
switch(step->getType())
|
||||
{
|
||||
case STEP_ANIMATION:
|
||||
{
|
||||
LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
|
||||
const LLUUID& anim_id = anim_step->mAnimAssetID;
|
||||
|
||||
// Don't request the animation if this step stops it or if it is already in Static VFS
|
||||
if (!(anim_id.isNull()
|
||||
|| anim_step->mFlags & ANIM_FLAG_STOP
|
||||
|| gAssetStorage->hasLocalAsset(anim_id, LLAssetType::AT_ANIMATION)))
|
||||
{
|
||||
mLoadingAssets.insert(anim_id);
|
||||
|
||||
LLUUID* id = new LLUUID(gAgentID);
|
||||
gAssetStorage->getAssetData(anim_id,
|
||||
LLAssetType::AT_ANIMATION,
|
||||
onAssetLoadComplete,
|
||||
(void *)id,
|
||||
TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STEP_SOUND:
|
||||
{
|
||||
LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
|
||||
const LLUUID& sound_id = sound_step->mSoundAssetID;
|
||||
if (!(sound_id.isNull()
|
||||
|| gAssetStorage->hasLocalAsset(sound_id, LLAssetType::AT_SOUND)))
|
||||
{
|
||||
mLoadingAssets.insert(sound_id);
|
||||
|
||||
gAssetStorage->getAssetData(sound_id,
|
||||
LLAssetType::AT_SOUND,
|
||||
onAssetLoadComplete,
|
||||
NULL,
|
||||
TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STEP_CHAT:
|
||||
case STEP_WAIT:
|
||||
case STEP_EOF:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
llwarns << "Unknown gesture step type: " << step->getType() << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// And get it going
|
||||
stepGesture(gesture);
|
||||
|
||||
@@ -711,8 +807,7 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LLVOAvatar* avatar = gAgentAvatarp;
|
||||
if (!avatar) return;
|
||||
if (!isAgentAvatarValid() || hasLoadingAssets(gesture)) return;
|
||||
|
||||
// Of the ones that started playing, have any stopped?
|
||||
|
||||
@@ -723,8 +818,8 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)
|
||||
{
|
||||
// look in signaled animations (simulator's view of what is
|
||||
// currently playing.
|
||||
LLVOAvatar::AnimIterator play_it = avatar->mSignaledAnimations.find(*gest_it);
|
||||
if (play_it != avatar->mSignaledAnimations.end())
|
||||
LLVOAvatar::AnimIterator play_it = gAgentAvatarp->mSignaledAnimations.find(*gest_it);
|
||||
if (play_it != gAgentAvatarp->mSignaledAnimations.end())
|
||||
{
|
||||
++gest_it;
|
||||
}
|
||||
@@ -742,8 +837,8 @@ void LLGestureMgr::stepGesture(LLMultiGesture* gesture)
|
||||
gest_it != gesture->mRequestedAnimIDs.end();
|
||||
)
|
||||
{
|
||||
LLVOAvatar::AnimIterator play_it = avatar->mSignaledAnimations.find(*gest_it);
|
||||
if (play_it != avatar->mSignaledAnimations.end())
|
||||
LLVOAvatar::AnimIterator play_it = gAgentAvatarp->mSignaledAnimations.find(*gest_it);
|
||||
if (play_it != gAgentAvatarp->mSignaledAnimations.end())
|
||||
{
|
||||
// Hooray, this animation has started playing!
|
||||
// Copy into playing.
|
||||
@@ -998,10 +1093,22 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs,
|
||||
}
|
||||
}
|
||||
|
||||
LLViewerInventoryItem* item = gInventory.getItem(item_id);
|
||||
if(item)
|
||||
{
|
||||
gesture->mName = item->getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Watch this item and set gesture name when item exists in inventory
|
||||
self.setFetchID(item_id);
|
||||
self.startFetch();
|
||||
}
|
||||
self.mActive[item_id] = gesture;
|
||||
|
||||
// Everything has been successful. Add to the active list.
|
||||
gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
|
||||
|
||||
if (inform_server)
|
||||
{
|
||||
// Inform the database of this change
|
||||
@@ -1019,6 +1126,13 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs,
|
||||
|
||||
gAgent.sendReliableMessage();
|
||||
}
|
||||
callback_map_t::iterator i_cb = self.mCallbackMap.find(item_id);
|
||||
|
||||
if(i_cb != self.mCallbackMap.end())
|
||||
{
|
||||
i_cb->second(gesture);
|
||||
self.mCallbackMap.erase(i_cb);
|
||||
}
|
||||
|
||||
self.notifyObservers();
|
||||
}
|
||||
@@ -1055,7 +1169,98 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs,
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLGestureMgr::onAssetLoadComplete(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status)
|
||||
{
|
||||
LLGestureMgr& self = LLGestureMgr::instance();
|
||||
|
||||
// Complete the asset loading process depending on the type and
|
||||
// remove the asset id from pending downloads list.
|
||||
switch(type)
|
||||
{
|
||||
case LLAssetType::AT_ANIMATION:
|
||||
{
|
||||
LLKeyframeMotion::onLoadComplete(vfs, asset_uuid, type, user_data, status, ext_status);
|
||||
|
||||
self.mLoadingAssets.erase(asset_uuid);
|
||||
|
||||
break;
|
||||
}
|
||||
case LLAssetType::AT_SOUND:
|
||||
{
|
||||
LLAudioEngine::assetCallback(vfs, asset_uuid, type, user_data, status, ext_status);
|
||||
|
||||
self.mLoadingAssets.erase(asset_uuid);
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
llwarns << "Unexpected asset type: " << type << llendl;
|
||||
|
||||
// We don't want to return from this callback without
|
||||
// an animation or sound callback being fired
|
||||
// and *user_data handled to avoid memory leaks.
|
||||
llassert(type == LLAssetType::AT_ANIMATION || type == LLAssetType::AT_SOUND);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLGestureMgr::hasLoadingAssets(LLMultiGesture* gesture)
|
||||
{
|
||||
LLGestureMgr& self = LLGestureMgr::instance();
|
||||
|
||||
for (std::vector<LLGestureStep*>::iterator steps_it = gesture->mSteps.begin();
|
||||
steps_it != gesture->mSteps.end();
|
||||
++steps_it)
|
||||
{
|
||||
LLGestureStep* step = *steps_it;
|
||||
switch(step->getType())
|
||||
{
|
||||
case STEP_ANIMATION:
|
||||
{
|
||||
LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
|
||||
const LLUUID& anim_id = anim_step->mAnimAssetID;
|
||||
|
||||
if (!(anim_id.isNull()
|
||||
|| anim_step->mFlags & ANIM_FLAG_STOP
|
||||
|| self.mLoadingAssets.find(anim_id) == self.mLoadingAssets.end()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STEP_SOUND:
|
||||
{
|
||||
LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
|
||||
const LLUUID& sound_id = sound_step->mSoundAssetID;
|
||||
|
||||
if (!(sound_id.isNull()
|
||||
|| self.mLoadingAssets.find(sound_id) == self.mLoadingAssets.end()))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case STEP_CHAT:
|
||||
case STEP_WAIT:
|
||||
case STEP_EOF:
|
||||
{
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
llwarns << "Unknown gesture step type: " << step->getType() << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLGestureMgr::stopGesture(LLMultiGesture* gesture)
|
||||
{
|
||||
@@ -1181,6 +1386,27 @@ void LLGestureMgr::getItemIDs(uuid_vec_t* ids)
|
||||
}
|
||||
}
|
||||
|
||||
void LLGestureMgr::done()
|
||||
{
|
||||
bool notify = false;
|
||||
for(item_map_t::iterator it = mActive.begin(); it != mActive.end(); ++it)
|
||||
{
|
||||
if(it->second && it->second->mName.empty())
|
||||
{
|
||||
LLViewerInventoryItem* item = gInventory.getItem(it->first);
|
||||
if(item)
|
||||
{
|
||||
it->second->mName = item->getName();
|
||||
notify = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(notify)
|
||||
{
|
||||
notifyObservers();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
const LLUUID& get_linked_uuid(const LLUUID &item_id)
|
||||
{
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llgesturemgr.h
|
||||
* @brief Manager for playing gestures on the viewer
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2004-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2004&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -38,6 +32,8 @@
|
||||
#include <vector>
|
||||
|
||||
#include "llassetstorage.h" // LLAssetType
|
||||
#include "llinventoryobserver.h"
|
||||
#include "llsingleton.h"
|
||||
#include "llviewerinventory.h"
|
||||
|
||||
class LLMultiGesture;
|
||||
@@ -52,11 +48,14 @@ public:
|
||||
virtual void changed() = 0;
|
||||
};
|
||||
|
||||
class LLGestureMgr : public LLSingleton<LLGestureMgr>
|
||||
class LLGestureMgr : public LLSingleton<LLGestureMgr>, public LLInventoryFetchItemsObserver
|
||||
{
|
||||
public:
|
||||
|
||||
typedef boost::function<void (LLMultiGesture* loaded_gesture)> gesture_loaded_callback_t;
|
||||
// Maps inventory item_id to gesture
|
||||
typedef std::map<LLUUID, LLMultiGesture*> item_map_t;
|
||||
typedef std::map<LLUUID, gesture_loaded_callback_t> callback_map_t;
|
||||
|
||||
LLGestureMgr();
|
||||
~LLGestureMgr();
|
||||
@@ -110,7 +109,15 @@ public:
|
||||
// Also remove from playing list
|
||||
void stopGesture(LLMultiGesture* gesture);
|
||||
void stopGesture(const LLUUID& item_id);
|
||||
|
||||
/**
|
||||
* Add cb into callbackMap.
|
||||
* Note:
|
||||
* Manager will call cb after gesture will be loaded and will remove cb automatically.
|
||||
*/
|
||||
void setGestureLoadedCallback(LLUUID inv_item_id, gesture_loaded_callback_t cb)
|
||||
{
|
||||
mCallbackMap[inv_item_id] = cb;
|
||||
}
|
||||
// Trigger the first gesture that matches this key.
|
||||
// Returns TRUE if it finds a gesture bound to that key.
|
||||
BOOL triggerGesture(KEY key, MASK mask);
|
||||
@@ -127,6 +134,9 @@ public:
|
||||
void removeObserver(LLGestureManagerObserver* observer);
|
||||
void notifyObservers();
|
||||
|
||||
// Overriding so we can update active gesture names and notify observers
|
||||
void changed(U32 mask);
|
||||
|
||||
BOOL matchPrefix(const std::string& in_str, std::string* out_str);
|
||||
|
||||
// Copy item ids into the vector
|
||||
@@ -139,14 +149,25 @@ protected:
|
||||
// Do a single step in a gesture
|
||||
void runStep(LLMultiGesture* gesture, LLGestureStep* step);
|
||||
|
||||
// LLInventoryCompletionObserver trigger
|
||||
void done();
|
||||
|
||||
// Used by loadGesture
|
||||
static void onLoadComplete(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
|
||||
// Used by playGesture to load an asset file
|
||||
// required to play a gesture step
|
||||
static void onAssetLoadComplete(LLVFS *vfs,
|
||||
const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
|
||||
|
||||
// Checks whether all animation and sound assets
|
||||
// needed to play a gesture are loaded.
|
||||
static bool hasLoadingAssets(LLMultiGesture* gesture);
|
||||
|
||||
private:
|
||||
// Active gestures.
|
||||
@@ -157,9 +178,13 @@ private:
|
||||
|
||||
S32 mLoadingCount;
|
||||
std::string mDeactivateSimilarNames;
|
||||
|
||||
|
||||
std::vector<LLGestureManagerObserver*> mObservers;
|
||||
callback_map_t mCallbackMap;
|
||||
std::vector<LLMultiGesture*> mPlaying;
|
||||
BOOL mValid;
|
||||
|
||||
std::set<LLUUID> mLoadingAssets;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -417,7 +417,7 @@ void LLGroupNotifyBox::moveToBack()
|
||||
{
|
||||
// Move this dialog to the back.
|
||||
gNotifyBoxView->removeChild(this);
|
||||
gNotifyBoxView->addChildAtEnd(this);
|
||||
gNotifyBoxView->addChildInBack(this);
|
||||
mNextBtn->setVisible(FALSE);
|
||||
|
||||
// And enable the next button on the frontmost one, if there is one
|
||||
|
||||
@@ -1344,10 +1344,7 @@ LLFloaterIMPanel::~LLFloaterIMPanel()
|
||||
mVoiceChannel = NULL;
|
||||
|
||||
//delete focus lost callback
|
||||
if(mInputEditor)
|
||||
{
|
||||
mInputEditor->setFocusLostCallback( NULL );
|
||||
}
|
||||
mFocusLostSignal.disconnect();
|
||||
}
|
||||
|
||||
BOOL LLFloaterIMPanel::postBuild()
|
||||
@@ -1360,8 +1357,8 @@ BOOL LLFloaterIMPanel::postBuild()
|
||||
mRPMode = false;
|
||||
|
||||
mInputEditor = getChild<LLLineEditor>("chat_editor");
|
||||
mInputEditor->setFocusReceivedCallback( onInputEditorFocusReceived, this );
|
||||
mInputEditor->setFocusLostCallback( onInputEditorFocusLost, this );
|
||||
mInputEditor->setFocusReceivedCallback( boost::bind(&LLFloaterIMPanel::onInputEditorFocusReceived, this) );
|
||||
mFocusLostSignal = mInputEditor->setFocusLostCallback( boost::bind(&LLFloaterIMPanel::onInputEditorFocusLost, this) );
|
||||
mInputEditor->setKeystrokeCallback( onInputEditorKeystroke );
|
||||
mInputEditor->setCommitCallback( onCommitChat );
|
||||
mInputEditor->setCallbackUserData(this);
|
||||
@@ -2005,18 +2002,14 @@ void LLFloaterIMPanel::onCommitChat(LLUICtrl* caller, void* userdata)
|
||||
self->sendMsg();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterIMPanel::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
|
||||
void LLFloaterIMPanel::onInputEditorFocusReceived()
|
||||
{
|
||||
LLFloaterIMPanel* self= (LLFloaterIMPanel*) userdata;
|
||||
self->mHistoryEditor->setCursorAndScrollToEnd();
|
||||
mHistoryEditor->setCursorAndScrollToEnd();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterIMPanel::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
|
||||
void LLFloaterIMPanel::onInputEditorFocusLost()
|
||||
{
|
||||
LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
|
||||
self->setTyping(FALSE);
|
||||
setTyping(FALSE);
|
||||
}
|
||||
|
||||
// static
|
||||
|
||||
@@ -231,8 +231,8 @@ public:
|
||||
void *cargo_data, EAcceptance *accept,
|
||||
std::string& tooltip_msg);
|
||||
|
||||
static void onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata );
|
||||
static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
|
||||
void onInputEditorFocusReceived();
|
||||
void onInputEditorFocusLost();
|
||||
static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
|
||||
static void onCommitChat(LLUICtrl* caller, void* userdata);
|
||||
static void onTabClick( void* userdata );
|
||||
@@ -382,6 +382,10 @@ private:
|
||||
// Timer to detect when user has stopped typing.
|
||||
LLFrameTimer mLastKeystrokeTimer;
|
||||
|
||||
boost::signals2::connection mFocusLostSignal;
|
||||
|
||||
|
||||
|
||||
void disableWhileSessionStarting();
|
||||
|
||||
typedef std::map<LLUUID, LLStyleSP> styleMap;
|
||||
|
||||
@@ -35,12 +35,13 @@
|
||||
#include <utility> // for std::pair<>
|
||||
|
||||
#include "llinventorypanel.h"
|
||||
#include "llpanelinventory.h"
|
||||
#include "llpanelobjectinventory.h"
|
||||
#include "llinventorybridge.h"
|
||||
|
||||
#include "message.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llcallingcard.h"
|
||||
#include "llcheckboxctrl.h" // for radio buttons
|
||||
#include "llfoldervieweventlistener.h"
|
||||
@@ -105,7 +106,7 @@ const std::string NEW_LSL_NAME = "New Script"; // *TODO:Translate? (probably not
|
||||
const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably not)
|
||||
const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
|
||||
|
||||
typedef LLMemberListener<LLPanelInventory> object_inventory_listener_t;
|
||||
typedef LLMemberListener<LLPanelObjectInventory> object_inventory_listener_t;
|
||||
typedef LLMemberListener<LLInventoryView> inventory_listener_t;
|
||||
typedef LLMemberListener<LLInventoryPanel> inventory_panel_listener_t;
|
||||
|
||||
@@ -128,8 +129,7 @@ bool doToSelected(LLFolderView* folder, std::string action)
|
||||
LLInventoryClipboard::instance().reset();
|
||||
}
|
||||
|
||||
std::set<LLUUID> selected_items;
|
||||
folder->getSelectionList(selected_items);
|
||||
std::set<LLUUID> selected_items = folder->getSelectionList();
|
||||
|
||||
LLMultiPreview* multi_previewp = NULL;
|
||||
LLMultiProperties* multi_propertiesp = NULL;
|
||||
@@ -165,15 +165,9 @@ bool doToSelected(LLFolderView* folder, std::string action)
|
||||
LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
|
||||
if(!bridge) continue;
|
||||
|
||||
bridge->performAction(folder, model, action);
|
||||
bridge->performAction(model, action);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
LLFloater::setFloaterHost(NULL);
|
||||
if (multi_previewp)
|
||||
{
|
||||
@@ -192,7 +186,7 @@ class LLDoToSelectedPanel : public object_inventory_listener_t
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
std::string action = userdata.asString();
|
||||
LLPanelInventory *panel = mPtr;
|
||||
LLPanelObjectInventory *panel = mPtr;
|
||||
LLFolderView* folder = panel->getRootFolder();
|
||||
if(!folder) return true;
|
||||
|
||||
@@ -237,7 +231,7 @@ class LLNewWindow : public inventory_listener_t
|
||||
LLInventoryView* iv = new LLInventoryView(std::string("Inventory"),
|
||||
rect,
|
||||
mPtr->getActivePanel()->getModel());
|
||||
iv->getActivePanel()->setFilterTypes(mPtr->getActivePanel()->getFilterTypes());
|
||||
iv->getActivePanel()->setFilterTypes(mPtr->getActivePanel()->getFilterObjectTypes());
|
||||
iv->getActivePanel()->setFilterSubString(mPtr->getActivePanel()->getFilterSubString());
|
||||
iv->open(); /*Flawfinder: ignore*/
|
||||
|
||||
@@ -391,12 +385,7 @@ void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, std::string type,
|
||||
else
|
||||
{
|
||||
LLWearableType::EType wear_type = LLWearableType::typeNameToType(type);
|
||||
if(wear_type != LLWearableType::WT_NONE)
|
||||
{
|
||||
LLFolderType::EType folder_type = LLFolderType::assetTypeToFolderType(LLWearableType::getAssetType(wear_type));
|
||||
LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(folder_type);
|
||||
LLFolderBridge::createWearable(parent_id, wear_type);
|
||||
}
|
||||
LLAgentWearables::createWearable(wear_type, false, self ? self->getUUID() : LLUUID::null);
|
||||
}
|
||||
ptr->getRootFolder()->setNeedsAutoRename(TRUE);
|
||||
}
|
||||
@@ -547,8 +536,7 @@ class LLBeginIMSession : public inventory_panel_listener_t
|
||||
LLInventoryPanel *panel = mPtr;
|
||||
LLInventoryModel* model = panel->getModel();
|
||||
if(!model) return true;
|
||||
std::set<LLUUID> selected_items;
|
||||
panel->getRootFolder()->getSelectionList(selected_items);
|
||||
std::set<LLUUID> selected_items = panel->getRootFolder()->getSelectionList();
|
||||
|
||||
std::string name;
|
||||
static int session_num = 1;
|
||||
@@ -653,8 +641,7 @@ class LLAttachObject : public inventory_panel_listener_t
|
||||
LLFolderView* folder = panel->getRootFolder();
|
||||
if(!folder) return true;
|
||||
|
||||
std::set<LLUUID> selected_items;
|
||||
folder->getSelectionList(selected_items);
|
||||
std::set<LLUUID> selected_items = folder->getSelectionList();
|
||||
LLUUID id = *selected_items.begin();
|
||||
|
||||
std::string joint_name = userdata.asString();
|
||||
@@ -709,7 +696,7 @@ class LL : public listener_t
|
||||
};
|
||||
*/
|
||||
|
||||
void init_object_inventory_panel_actions(LLPanelInventory *panel)
|
||||
void init_object_inventory_panel_actions(LLPanelObjectInventory *panel)
|
||||
{
|
||||
(new LLDoToSelectedPanel())->registerListener(panel, "Inventory.DoToSelected");
|
||||
}
|
||||
|
||||
@@ -489,8 +489,7 @@ void LLInventoryBackup::save(LLFolderView* folder)
|
||||
{
|
||||
LLInventoryModel* model = &gInventory;
|
||||
|
||||
std::set<LLUUID> selected_items;
|
||||
folder->getSelectionList(selected_items);
|
||||
std::set<LLUUID> selected_items = folder->getSelectionList();
|
||||
|
||||
if(selected_items.size() < 1)
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,31 +2,25 @@
|
||||
* @file llinventorybridge.h
|
||||
* @brief Implementation of the Inventory-Folder-View-Bridge classes.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -38,7 +32,6 @@
|
||||
#include "llfoldervieweventlistener.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llinventoryobserver.h"
|
||||
//#include "llinventoryview.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llwearable.h"
|
||||
|
||||
@@ -48,75 +41,9 @@ class LLMenuGL;
|
||||
class LLCallingCardObserver;
|
||||
class LLViewerJointAttachment;
|
||||
|
||||
|
||||
typedef std::vector<std::string> menuentry_vec_t;
|
||||
|
||||
struct LLAttachmentRezAction
|
||||
{
|
||||
LLUUID mItemID;
|
||||
S32 mAttachPt;
|
||||
};
|
||||
|
||||
// [RLVa:KB] - Checked: 2009-12-18 (RLVa-1.1.0i) | Added: RLVa-1.1.0i
|
||||
// Moved from llinventorybridge.cpp because we need it in RlvForceWearLegacy
|
||||
struct LLFoundData
|
||||
{
|
||||
LLFoundData(const LLUUID& item_id,
|
||||
const LLUUID& asset_id,
|
||||
const std::string& name,
|
||||
LLAssetType::EType asset_type) :
|
||||
mItemID(item_id),
|
||||
mAssetID(asset_id),
|
||||
mName(name),
|
||||
mAssetType(asset_type),
|
||||
mWearable( NULL ) {}
|
||||
|
||||
LLUUID mItemID;
|
||||
LLUUID mAssetID;
|
||||
std::string mName;
|
||||
LLAssetType::EType mAssetType;
|
||||
LLWearable* mWearable;
|
||||
};
|
||||
|
||||
struct LLWearableHoldingPattern
|
||||
{
|
||||
LLWearableHoldingPattern(BOOL fAddToOutfit) : mResolved(0), mAddToOutfit(fAddToOutfit) {}
|
||||
~LLWearableHoldingPattern()
|
||||
{
|
||||
for_each(mFoundList.begin(), mFoundList.end(), DeletePointer());
|
||||
mFoundList.clear();
|
||||
}
|
||||
typedef std::list<LLFoundData*> found_list_t;
|
||||
found_list_t mFoundList;
|
||||
S32 mResolved;
|
||||
BOOL mAddToOutfit;
|
||||
};
|
||||
// [/RLVa:KB]
|
||||
|
||||
//helper functions
|
||||
class LLShowProps
|
||||
{
|
||||
public:
|
||||
|
||||
static void showProperties(const LLUUID& uuid)
|
||||
{
|
||||
if(!LLFloaterProperties::show(uuid, LLUUID::null))
|
||||
{
|
||||
S32 left, top;
|
||||
gFloaterView->getNewFloaterPosition(&left, &top);
|
||||
LLRect rect = gSavedSettings.getRect("PropertiesRect");
|
||||
rect.translate( left - rect.mLeft, top - rect.mTop );
|
||||
LLFloaterProperties* floater;
|
||||
floater = new LLFloaterProperties("item properties",
|
||||
rect,
|
||||
"Inventory Item Properties",
|
||||
uuid,
|
||||
LLUUID::null);
|
||||
// keep onscreen
|
||||
gFloaterView->adjustToFitScreen(floater, FALSE);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLInvFVBridge (& it's derived classes)
|
||||
//
|
||||
@@ -125,7 +52,7 @@ public:
|
||||
//
|
||||
// You'll want to call LLInvItemFVELister::createBridge() to actually create
|
||||
// an instance of this class. This helps encapsulate the
|
||||
// funcationality a bit. (except for folders, you can create those
|
||||
// functionality a bit. (except for folders, you can create those
|
||||
// manually...)
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLInvFVBridge : public LLFolderViewEventListener
|
||||
@@ -137,6 +64,7 @@ public:
|
||||
LLAssetType::EType actual_asset_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
LLInventoryPanel* inventory,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid,
|
||||
U32 flags = 0x00);
|
||||
virtual ~LLInvFVBridge() {}
|
||||
@@ -162,12 +90,13 @@ public:
|
||||
virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
|
||||
virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
|
||||
virtual void openItem() {}
|
||||
virtual void closeItem() {}
|
||||
virtual void previewItem() {openItem();}
|
||||
virtual void showProperties();
|
||||
virtual BOOL isItemRenameable() const { return TRUE; }
|
||||
//virtual BOOL renameItem(const std::string& new_name) {}
|
||||
virtual BOOL isItemRemovable();
|
||||
virtual BOOL isItemMovable();
|
||||
virtual BOOL isItemRemovable() const;
|
||||
virtual BOOL isItemMovable() const;
|
||||
virtual BOOL isItemInTrash() const;
|
||||
virtual BOOL isLink() const;
|
||||
//virtual BOOL removeItem() = 0;
|
||||
@@ -175,7 +104,7 @@ public:
|
||||
virtual void move(LLFolderViewEventListener* new_parent_bridge) {}
|
||||
virtual BOOL isItemCopyable() const { return FALSE; }
|
||||
virtual BOOL copyToClipboard() const { return FALSE; }
|
||||
virtual BOOL cutToClipboard() const { return FALSE; }
|
||||
virtual void cutToClipboard();
|
||||
virtual BOOL isClipboardPasteable() const;
|
||||
virtual BOOL isClipboardPasteableAsLink() const;
|
||||
virtual void pasteFromClipboard() {}
|
||||
@@ -190,6 +119,9 @@ public:
|
||||
virtual LLInventoryType::EType getInventoryType() const { return mInvType; }
|
||||
virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Convenience functions for adding various common menu options.
|
||||
//--------------------------------------------------------------------
|
||||
protected:
|
||||
virtual void addTrashContextMenuOptions(menuentry_vec_t &items,
|
||||
menuentry_vec_t &disabled_items);
|
||||
@@ -197,15 +129,14 @@ protected:
|
||||
menuentry_vec_t &disabled_items);
|
||||
virtual void addOpenRightClickMenuOption(menuentry_vec_t &items);
|
||||
protected:
|
||||
LLInvFVBridge(LLInventoryPanel* inventory, /*LLFolderView* root,*/ const LLUUID& uuid);
|
||||
LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid);
|
||||
|
||||
LLInventoryObject* getInventoryObject() const;
|
||||
LLInventoryModel* getInventoryModel() const;
|
||||
|
||||
BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash?
|
||||
BOOL isLinkedObjectMissing() const; // Is this a linked obj whose baseobj is not in inventory?
|
||||
// return true if the item is in agent inventory. if false, it
|
||||
// must be lost or in the inventory library.
|
||||
|
||||
BOOL isAgentInventory() const; // false if lost or in the inventory library
|
||||
BOOL isCOFFolder() const; // true if COF or descendent of
|
||||
virtual BOOL isItemPermissive() const;
|
||||
@@ -218,28 +149,48 @@ protected:
|
||||
const LLUUID& new_parent,
|
||||
BOOL restamp);
|
||||
void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch);
|
||||
|
||||
protected:
|
||||
LLInventoryPanel* mInventoryPanel;
|
||||
LLUUID mUUID; // item id
|
||||
LLHandle<LLPanel> mInventoryPanel;
|
||||
LLFolderView* mRoot;
|
||||
const LLUUID mUUID; // item id
|
||||
LLInventoryType::EType mInvType;
|
||||
BOOL mIsLink;
|
||||
void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
|
||||
};
|
||||
|
||||
class AIFilePicker;
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLInvFVBridgeBuilder
|
||||
//
|
||||
// This class intended to build Folder View Bridge via LLInvFVBridge::createBridge.
|
||||
// It can be overridden with another way of creation necessary Inventory-Folder-View-Bridge.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLInventoryFVBridgeBuilder
|
||||
{
|
||||
public:
|
||||
virtual ~LLInventoryFVBridgeBuilder() {}
|
||||
virtual LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
|
||||
LLAssetType::EType actual_asset_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
LLInventoryPanel* inventory,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid,
|
||||
U32 flags = 0x00) const;
|
||||
};
|
||||
|
||||
class LLItemBridge : public LLInvFVBridge
|
||||
{
|
||||
public:
|
||||
LLItemBridge(LLInventoryPanel* inventory, const LLUUID& uuid) :
|
||||
LLInvFVBridge(inventory, uuid) {}
|
||||
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
LLItemBridge(LLInventoryPanel* inventory,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLInvFVBridge(inventory, root, uuid) {}
|
||||
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void selectItem();
|
||||
virtual void restoreItem();
|
||||
virtual void restoreToWorld();
|
||||
virtual void gotoItem(LLFolderView *folder);
|
||||
virtual void gotoItem();
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual const std::string& getDisplayName() const;
|
||||
virtual std::string getLabelSuffix() const;
|
||||
@@ -261,26 +212,28 @@ public:
|
||||
LLViewerInventoryItem* getItem() const;
|
||||
|
||||
protected:
|
||||
BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response);
|
||||
virtual BOOL isItemPermissive() const;
|
||||
static void buildDisplayName(LLInventoryItem* item, std::string& name);
|
||||
|
||||
mutable std::string mDisplayName;
|
||||
};
|
||||
|
||||
|
||||
class LLFolderBridge : public LLInvFVBridge
|
||||
{
|
||||
public:
|
||||
LLFolderBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLInvFVBridge(inventory, /*root,*/ uuid),
|
||||
LLInvFVBridge(inventory, root, uuid),
|
||||
mCallingCards(FALSE),
|
||||
mWearables(FALSE)
|
||||
{}
|
||||
BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop);
|
||||
BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop);
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual void closeItem();
|
||||
virtual BOOL isItemRenameable() const;
|
||||
virtual void selectItem();
|
||||
virtual void restoreItem();
|
||||
@@ -293,6 +246,9 @@ public:
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
|
||||
virtual BOOL removeItem();
|
||||
BOOL removeSystemFolder();
|
||||
bool removeItemResponse(const LLSD& notification, const LLSD& response);
|
||||
|
||||
virtual void pasteFromClipboard();
|
||||
virtual void pasteLinkFromClipboard();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
@@ -301,23 +257,28 @@ public:
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data);
|
||||
|
||||
virtual BOOL isItemRemovable();
|
||||
virtual BOOL isItemMovable();
|
||||
virtual BOOL isItemRemovable() const;
|
||||
virtual BOOL isItemMovable() const ;
|
||||
virtual BOOL isUpToDate() const;
|
||||
virtual BOOL isItemCopyable() const;
|
||||
virtual BOOL isClipboardPasteable() const;
|
||||
virtual BOOL isClipboardPasteableAsLink() const;
|
||||
|
||||
virtual BOOL copyToClipboard() const;
|
||||
|
||||
static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type);
|
||||
static void createWearable(LLUUID parent_folder_id, LLWearableType::EType type);
|
||||
|
||||
LLViewerInventoryCategory* getCategory() const;
|
||||
LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }
|
||||
|
||||
protected:
|
||||
// menu callbacks
|
||||
void buildContextMenuBaseOptions(U32 flags);
|
||||
void buildContextMenuFolderOptions(U32 flags);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Menu callbacks
|
||||
//--------------------------------------------------------------------
|
||||
static void pasteClipboard(void* user_data);
|
||||
static void createNewCategory(void* user_data);
|
||||
|
||||
static void createNewShirt(void* user_data);
|
||||
static void createNewPants(void* user_data);
|
||||
static void createNewShoes(void* user_data);
|
||||
@@ -337,46 +298,55 @@ protected:
|
||||
|
||||
BOOL checkFolderForContentsOfType(LLInventoryModel* model, LLInventoryCollectFunctor& typeToCheck);
|
||||
|
||||
void modifyOutfit(BOOL append, BOOL replace = FALSE);
|
||||
void modifyOutfit(BOOL append);
|
||||
void determineFolderType();
|
||||
|
||||
menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items
|
||||
|
||||
void dropToFavorites(LLInventoryItem* inv_item);
|
||||
void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Messy hacks for handling folder options
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
static LLHandle<LLFolderBridge> sSelf;
|
||||
static void staticFolderOptionsMenu();
|
||||
void folderOptionsMenu();
|
||||
|
||||
private:
|
||||
BOOL mCallingCards;
|
||||
BOOL mWearables;
|
||||
LLHandle<LLView> mMenu;
|
||||
BOOL mCallingCards;
|
||||
BOOL mWearables;
|
||||
menuentry_vec_t mItems;
|
||||
menuentry_vec_t mDisabledItems;
|
||||
LLRootHandle<LLFolderBridge> mHandle;
|
||||
};
|
||||
|
||||
|
||||
class LLTextureBridge : public LLItemBridge
|
||||
{
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Texture: ");return ret; }
|
||||
LLTextureBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid,
|
||||
LLInventoryType::EType type) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid)
|
||||
LLItemBridge(inventory, root, uuid)
|
||||
{
|
||||
mInvType = type;
|
||||
}
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void openItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
bool canSaveTexture(void);
|
||||
};
|
||||
|
||||
class LLSoundBridge : public LLItemBridge
|
||||
{
|
||||
public:
|
||||
LLSoundBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
virtual void openItem();
|
||||
virtual void previewItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
@@ -390,10 +360,10 @@ public:
|
||||
static const std::string& prefix() { static std::string ret("Landmark: ");return ret; }
|
||||
virtual const std::string& getPrefix() { return prefix(); }
|
||||
LLLandmarkBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid,
|
||||
U32 flags = 0x00);
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void openItem();
|
||||
@@ -406,17 +376,15 @@ class LLCallingCardBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Calling Card: ");return ret; }
|
||||
LLCallingCardBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* folder,
|
||||
const LLUUID& uuid );
|
||||
~LLCallingCardBridge();
|
||||
virtual std::string getLabelSuffix() const;
|
||||
//virtual const std::string& getDisplayName() const;
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
//virtual void renameItem(const std::string& new_name);
|
||||
//virtual BOOL removeItem();
|
||||
virtual BOOL dragOrDrop(MASK mask, BOOL drop,
|
||||
EDragAndDropType cargo_type,
|
||||
void* cargo_data);
|
||||
@@ -431,9 +399,9 @@ class LLNotecardBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Notecard: ");return ret; }
|
||||
LLNotecardBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
virtual void openItem();
|
||||
};
|
||||
|
||||
@@ -442,17 +410,18 @@ class LLGestureBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Gesture: ");return ret; }
|
||||
LLGestureBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
// Only suffix for gesture items, not task items, because only
|
||||
// gestures in your inventory can be active.
|
||||
virtual LLFontGL::StyleFlags getLabelStyle() const;
|
||||
virtual std::string getLabelSuffix() const;
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual BOOL removeItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
static void playGesture(const LLUUID& item_id);
|
||||
};
|
||||
|
||||
|
||||
@@ -461,10 +430,10 @@ class LLAnimationBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Animation: ");return ret; }
|
||||
LLAnimationBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual void openItem();
|
||||
};
|
||||
@@ -475,20 +444,19 @@ class LLObjectBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Object: ");return ret; }
|
||||
LLObjectBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid,
|
||||
LLInventoryType::EType type,
|
||||
U32 flags);
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual std::string getLabelSuffix() const;
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual BOOL isItemRemovable();
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
LLInventoryObject* getObject() const;
|
||||
protected:
|
||||
static LLUUID sContextMenuItemID; // Only valid while the context menu is open.
|
||||
static LLUUID sContextMenuItemID; // Only valid while the context menu is open.
|
||||
U32 mAttachPt;
|
||||
BOOL mIsMultiObject;
|
||||
};
|
||||
@@ -498,28 +466,26 @@ class LLLSLTextBridge : public LLItemBridge
|
||||
public:
|
||||
virtual const std::string& getPrefix() { static std::string ret("Script: ");return ret; }
|
||||
LLLSLTextBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid ) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
virtual void openItem();
|
||||
};
|
||||
|
||||
|
||||
class LLWearableBridge : public LLItemBridge
|
||||
{
|
||||
public:
|
||||
LLWearableBridge(LLInventoryPanel* inventory,
|
||||
/*LLFolderView* root,*/
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid,
|
||||
LLAssetType::EType asset_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
LLWearableType::EType wearable_type);
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void openItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual std::string getLabelSuffix() const;
|
||||
virtual BOOL isItemRemovable();
|
||||
virtual BOOL renameItem(const std::string& new_name);
|
||||
virtual LLWearableType::EType getWearableType() const { return mWearableType; }
|
||||
|
||||
@@ -528,13 +494,19 @@ public:
|
||||
static void onWearOnAvatarArrived( LLWearable* wearable, void* userdata );
|
||||
void wearOnAvatar();
|
||||
|
||||
static void onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata );
|
||||
void wearAddOnAvatar();
|
||||
|
||||
static BOOL canEditOnAvatar( void* userdata ); // Access to editOnAvatar() from menu
|
||||
static void onEditOnAvatar( void* userdata );
|
||||
void editOnAvatar();
|
||||
|
||||
static BOOL canRemoveFromAvatar( void* userdata );
|
||||
static void onRemoveFromAvatar( void* userdata );
|
||||
static void onRemoveFromAvatarArrived( LLWearable* wearable, void* userdata );
|
||||
static void onRemoveFromAvatarArrived( LLWearable* wearable, void* userdata );
|
||||
static void removeItemFromAvatar(LLViewerInventoryItem *item);
|
||||
static void removeAllClothesFromAvatar();
|
||||
void removeFromAvatar();
|
||||
protected:
|
||||
LLAssetType::EType mAssetType;
|
||||
LLWearableType::EType mWearableType;
|
||||
@@ -544,9 +516,9 @@ class LLLinkItemBridge : public LLItemBridge
|
||||
{
|
||||
public:
|
||||
LLLinkItemBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
virtual const std::string& getPrefix() { return sPrefix; }
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
@@ -558,34 +530,103 @@ class LLLinkFolderBridge : public LLItemBridge
|
||||
{
|
||||
public:
|
||||
LLLinkFolderBridge(LLInventoryPanel* inventory,
|
||||
//LLFolderView* root,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, /*root,*/ uuid) {}
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
virtual const std::string& getPrefix() { return sPrefix; }
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
|
||||
virtual void gotoItem(LLFolderView *folder);
|
||||
virtual void performAction(LLInventoryModel* model, std::string action);
|
||||
virtual void gotoItem();
|
||||
protected:
|
||||
const LLUUID &getFolderID() const;
|
||||
static std::string sPrefix;
|
||||
};
|
||||
|
||||
|
||||
class LLMeshBridge : public LLItemBridge
|
||||
{
|
||||
friend class LLInvFVBridge;
|
||||
friend class LLInvFVBridge;
|
||||
public:
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void openItem();
|
||||
virtual void previewItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
virtual LLUIImagePtr getIcon() const;
|
||||
virtual void openItem();
|
||||
virtual void previewItem();
|
||||
virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
|
||||
protected:
|
||||
LLMeshBridge(LLInventoryPanel* inventory,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, uuid) {}
|
||||
LLMeshBridge(LLInventoryPanel* inventory,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLItemBridge(inventory, root, uuid) {}
|
||||
};
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLInvFVBridgeAction
|
||||
//
|
||||
// This is an implementation class to be able to
|
||||
// perform action to view inventory items.
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLInvFVBridgeAction
|
||||
{
|
||||
public:
|
||||
// This method is a convenience function which creates the correct
|
||||
// type of bridge action based on some basic information.
|
||||
static LLInvFVBridgeAction* createAction(LLAssetType::EType asset_type,
|
||||
const LLUUID& uuid,
|
||||
LLInventoryModel* model);
|
||||
static void doAction(LLAssetType::EType asset_type,
|
||||
const LLUUID& uuid, LLInventoryModel* model);
|
||||
static void doAction(const LLUUID& uuid, LLInventoryModel* model);
|
||||
|
||||
virtual void doIt() {};
|
||||
virtual ~LLInvFVBridgeAction() {} // need this because of warning on OSX
|
||||
protected:
|
||||
LLInvFVBridgeAction(const LLUUID& id, LLInventoryModel* model) :
|
||||
mUUID(id), mModel(model) {}
|
||||
LLViewerInventoryItem* getItem() const;
|
||||
protected:
|
||||
const LLUUID& mUUID; // item id
|
||||
LLInventoryModel* mModel;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Recent Inventory Panel related classes
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
// Overridden version of the Inventory-Folder-View-Bridge for Folders
|
||||
class LLRecentItemsFolderBridge : public LLFolderBridge
|
||||
{
|
||||
friend class LLInvFVBridgeAction;
|
||||
public:
|
||||
// Creates context menu for Folders related to Recent Inventory Panel.
|
||||
// Uses base logic and than removes from visible items "New..." menu items.
|
||||
LLRecentItemsFolderBridge(LLInventoryType::EType type,
|
||||
LLInventoryPanel* inventory,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid) :
|
||||
LLFolderBridge(inventory, root, uuid)
|
||||
{
|
||||
mInvType = type;
|
||||
}
|
||||
/*virtual*/ void buildContextMenu(LLMenuGL& menu, U32 flags);
|
||||
};
|
||||
|
||||
// Bridge builder to create Inventory-Folder-View-Bridge for Recent Inventory Panel
|
||||
class LLRecentInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder
|
||||
{
|
||||
public:
|
||||
// Overrides FolderBridge for Recent Inventory Panel.
|
||||
// It use base functionality for bridges other than FolderBridge.
|
||||
virtual LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
|
||||
LLAssetType::EType actual_asset_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
LLInventoryPanel* inventory,
|
||||
LLFolderView* root,
|
||||
const LLUUID& uuid,
|
||||
U32 flags = 0x00) const;
|
||||
};
|
||||
void rez_attachment(LLViewerInventoryItem* item,
|
||||
LLViewerJointAttachment* attachment,
|
||||
bool replace = false);
|
||||
@@ -597,4 +638,13 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
|
||||
BOOL drop,
|
||||
void (*callback)(S32, void*) = NULL,
|
||||
void* user_data = NULL);
|
||||
|
||||
// Utility function to hide all entries except those in the list
|
||||
// Can be called multiple times on the same menu (e.g. if multiple items
|
||||
// are selected). If "append" is false, then only common enabled items
|
||||
// are set as enabled.
|
||||
void hide_context_entries(LLMenuGL& menu,
|
||||
const menuentry_vec_t &entries_to_show,
|
||||
const menuentry_vec_t &disabled_entries);
|
||||
|
||||
#endif // LL_LLINVENTORYBRIDGE_H
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llinventoryclipboard.cpp
|
||||
* @brief LLInventoryClipboard class implementation
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -47,6 +41,7 @@ LLInventoryClipboard LLInventoryClipboard::sInstance;
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLInventoryClipboard::LLInventoryClipboard()
|
||||
: mCutMode(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -77,6 +72,16 @@ void LLInventoryClipboard::store(const LLDynamicArray<LLUUID>& inv_objects)
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryClipboard::cut(const LLUUID& object)
|
||||
{
|
||||
if(!mCutMode && !mObjects.empty())
|
||||
{
|
||||
//looks like there are some stored items, reset clipboard state
|
||||
reset();
|
||||
}
|
||||
mCutMode = true;
|
||||
add(object);
|
||||
}
|
||||
void LLInventoryClipboard::retrieve(LLDynamicArray<LLUUID>& inv_objects) const
|
||||
{
|
||||
inv_objects.reset();
|
||||
@@ -90,6 +95,7 @@ void LLInventoryClipboard::retrieve(LLDynamicArray<LLUUID>& inv_objects) const
|
||||
void LLInventoryClipboard::reset()
|
||||
{
|
||||
mObjects.reset();
|
||||
mCutMode = false;
|
||||
}
|
||||
|
||||
// returns true if the clipboard has something pasteable in it.
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llinventoryclipboard.h
|
||||
* @brief LLInventoryClipboard class header file
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -60,6 +54,7 @@ public:
|
||||
// this method stores an array of objects
|
||||
void store(const LLDynamicArray<LLUUID>& inventory_objects);
|
||||
|
||||
void cut(const LLUUID& object);
|
||||
// this method gets the objects in the clipboard by copying them
|
||||
// into the array provided.
|
||||
void retrieve(LLDynamicArray<LLUUID>& inventory_objects) const;
|
||||
@@ -69,11 +64,13 @@ public:
|
||||
|
||||
// returns true if the clipboard has something pasteable in it.
|
||||
BOOL hasContents() const;
|
||||
bool isCutMode() const { return mCutMode; }
|
||||
|
||||
protected:
|
||||
static LLInventoryClipboard sInstance;
|
||||
|
||||
LLDynamicArray<LLUUID> mObjects;
|
||||
bool mCutMode;
|
||||
|
||||
public:
|
||||
// please don't actually call these
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
// viewer includes
|
||||
#include "llfoldervieweventlistener.h"
|
||||
#include "llfolderview.h"
|
||||
#include "llfolderviewitem.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llinventorymodelbackgroundfetch.h"
|
||||
#include "llviewercontrol.h"
|
||||
@@ -44,12 +44,21 @@
|
||||
#include "lltrans.h"
|
||||
|
||||
LLInventoryFilter::FilterOps::FilterOps() :
|
||||
mFilterTypes(0xffffffff),
|
||||
mFilterObjectTypes(0xffffffffffffffffULL),
|
||||
mFilterCategoryTypes(0xffffffffffffffffULL),
|
||||
mFilterWearableTypes(0xffffffffffffffffULL),
|
||||
mMinDate(time_min()),
|
||||
mMaxDate(time_max()),
|
||||
mHoursAgo(0),
|
||||
mShowFolderState(SHOW_NON_EMPTY_FOLDERS),
|
||||
mPermissions(PERM_NONE) {}
|
||||
mPermissions(PERM_NONE),
|
||||
mFilterTypes(FILTERTYPE_OBJECT),
|
||||
mFilterWorn(false),
|
||||
mFilterUUID(LLUUID::null),
|
||||
mFilterLinks(FILTERLINK_INCLUDE_LINKS)
|
||||
{
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLInventoryFilter
|
||||
///----------------------------------------------------------------------------
|
||||
@@ -62,7 +71,6 @@ LLInventoryFilter::LLInventoryFilter(const std::string& name)
|
||||
|
||||
mSubStringMatchOffset = 0;
|
||||
mFilterSubString.clear();
|
||||
mFilterWorn = false;
|
||||
mFilterGeneration = 0;
|
||||
mMustPassGeneration = S32_MAX;
|
||||
mMinRequiredGeneration = 0;
|
||||
@@ -82,36 +90,184 @@ LLInventoryFilter::~LLInventoryFilter()
|
||||
|
||||
BOOL LLInventoryFilter::check(LLFolderViewItem* item)
|
||||
{
|
||||
LLFolderViewEventListener* listener = item->getListener();
|
||||
const LLUUID& item_id = listener->getUUID();
|
||||
const LLInventoryObject *obj = gInventory.getObject(item_id);
|
||||
if (isActive() && obj && obj->getIsLinkType())
|
||||
// If it's a folder and we're showing all folders, return TRUE automatically.
|
||||
const BOOL is_folder = (dynamic_cast<const LLFolderViewFolder*>(item) != NULL);
|
||||
if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
|
||||
{
|
||||
// When filtering is active, omit links.
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
time_t earliest;
|
||||
const LLFolderViewEventListener* listener = item->getListener();
|
||||
const LLUUID item_id = listener ? listener->getUUID() : LLUUID::null;
|
||||
|
||||
earliest = time_corrected() - mFilterOps.mHoursAgo * 3600;
|
||||
if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
|
||||
{
|
||||
earliest = mFilterOps.mMinDate;
|
||||
}
|
||||
else if (!mFilterOps.mHoursAgo)
|
||||
{
|
||||
earliest = 0;
|
||||
}
|
||||
mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
|
||||
BOOL passed = (0x1 << listener->getInventoryType() & mFilterOps.mFilterTypes || listener->getInventoryType() == LLInventoryType::IT_NONE)
|
||||
&& (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos)
|
||||
&& (mFilterWorn == false || gAgentWearables.isWearingItem(item_id) ||
|
||||
(gAgentAvatarp && gAgentAvatarp->isWearingAttachment(item_id)))
|
||||
&& ((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions)
|
||||
&& (listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate);
|
||||
|
||||
const BOOL passed_filtertype = checkAgainstFilterType(item);
|
||||
const BOOL passed_permissions = checkAgainstPermissions(item);
|
||||
const BOOL passed_filterlink = checkAgainstFilterLinks(item);
|
||||
const BOOL passed_wearable = !mFilterOps.mFilterWorn || (gAgentWearables.isWearingItem(item_id) || (gAgentAvatarp && gAgentAvatarp->isWearingAttachment(item_id)));
|
||||
const BOOL passed = (passed_filtertype &&
|
||||
passed_permissions &&
|
||||
passed_filterlink &&
|
||||
passed_wearable &&
|
||||
(mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
|
||||
|
||||
return passed;
|
||||
}
|
||||
|
||||
bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder)
|
||||
{
|
||||
// we're showing all folders, overriding filter
|
||||
if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
const LLFolderViewEventListener* listener = folder->getListener();
|
||||
const LLUUID folder_id = listener->getUUID();
|
||||
|
||||
if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
|
||||
{
|
||||
// Can only filter categories for items in your inventory
|
||||
// (e.g. versus in-world object contents).
|
||||
const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
|
||||
if (!cat)
|
||||
return false;
|
||||
LLFolderType::EType cat_type = cat->getPreferredType();
|
||||
if (cat_type != LLFolderType::FT_NONE && (1LL << cat_type & mFilterOps.mFilterCategoryTypes) == U64(0))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
|
||||
{
|
||||
const LLFolderViewEventListener* listener = item->getListener();
|
||||
if (!listener) return FALSE;
|
||||
|
||||
LLInventoryType::EType object_type = listener->getInventoryType();
|
||||
const LLUUID object_id = listener->getUUID();
|
||||
const LLInventoryObject *object = gInventory.getObject(object_id);
|
||||
|
||||
const U32 filterTypes = mFilterOps.mFilterTypes;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// FILTERTYPE_OBJECT
|
||||
// Pass if this item's type is of the correct filter type
|
||||
if (filterTypes & FILTERTYPE_OBJECT)
|
||||
{
|
||||
// If it has no type, pass it, unless it's a link.
|
||||
if (object_type == LLInventoryType::IT_NONE)
|
||||
{
|
||||
if (object && object->getIsLinkType())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// FILTERTYPE_UUID
|
||||
// Pass if this item is the target UUID or if it links to the target UUID
|
||||
if (filterTypes & FILTERTYPE_UUID)
|
||||
{
|
||||
if (!object) return FALSE;
|
||||
|
||||
if (object->getLinkedUUID() != mFilterOps.mFilterUUID)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// FILTERTYPE_DATE
|
||||
// Pass if this item is within the date range.
|
||||
if (filterTypes & FILTERTYPE_DATE)
|
||||
{
|
||||
const U16 HOURS_TO_SECONDS = 3600;
|
||||
time_t earliest = time_corrected() - mFilterOps.mHoursAgo * HOURS_TO_SECONDS;
|
||||
if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
|
||||
{
|
||||
earliest = mFilterOps.mMinDate;
|
||||
}
|
||||
else if (!mFilterOps.mHoursAgo)
|
||||
{
|
||||
earliest = 0;
|
||||
}
|
||||
if (listener->getCreationDate() < earliest ||
|
||||
listener->getCreationDate() > mFilterOps.mMaxDate)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// FILTERTYPE_WEARABLE
|
||||
// Pass if this item is a wearable of the appropriate type
|
||||
if (filterTypes & FILTERTYPE_WEARABLE)
|
||||
{
|
||||
LLWearableType::EType type = listener->getWearableType();
|
||||
if ((0x1LL << type & mFilterOps.mFilterWearableTypes) == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// FILTERTYPE_EMPTYFOLDERS
|
||||
// Pass if this item is a folder and is not a system folder that should be hidden
|
||||
if (filterTypes & FILTERTYPE_EMPTYFOLDERS)
|
||||
{
|
||||
if (object_type == LLInventoryType::IT_CATEGORY)
|
||||
{
|
||||
bool is_hidden_if_empty = LLViewerFolderType::lookupIsHiddenIfEmpty(listener->getPreferredType());
|
||||
if (is_hidden_if_empty)
|
||||
{
|
||||
// Force the fetching of those folders so they are hidden iff they really are empty...
|
||||
gInventory.fetchDescendentsOf(object_id);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
|
||||
{
|
||||
const LLFolderViewEventListener* listener = item->getListener();
|
||||
if (!listener) return FALSE;
|
||||
|
||||
PermissionMask perm = listener->getPermissionMask();
|
||||
const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(item->getListener());
|
||||
if (bridge && bridge->isLink())
|
||||
{
|
||||
const LLUUID& linked_uuid = gInventory.getLinkedItemID(bridge->getUUID());
|
||||
const LLViewerInventoryItem *linked_item = gInventory.getItem(linked_uuid);
|
||||
if (linked_item)
|
||||
perm = linked_item->getPermissionMask();
|
||||
}
|
||||
return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
|
||||
{
|
||||
const LLFolderViewEventListener* listener = item->getListener();
|
||||
if (!listener) return TRUE;
|
||||
|
||||
const LLUUID object_id = listener->getUUID();
|
||||
const LLInventoryObject *object = gInventory.getObject(object_id);
|
||||
if (!object) return TRUE;
|
||||
|
||||
const BOOL is_link = object->getIsLinkType();
|
||||
if (is_link && (mFilterOps.mFilterLinks == FILTERLINK_EXCLUDE_LINKS))
|
||||
return FALSE;
|
||||
if (!is_link && (mFilterOps.mFilterLinks == FILTERLINK_ONLY_LINKS))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
|
||||
{
|
||||
return mFilterSubString;
|
||||
@@ -125,20 +281,32 @@ std::string::size_type LLInventoryFilter::getStringMatchOffset() const
|
||||
// has user modified default filter params?
|
||||
BOOL LLInventoryFilter::isNotDefault() const
|
||||
{
|
||||
return mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes
|
||||
|| mFilterSubString.size()
|
||||
|| mFilterWorn
|
||||
|| mFilterOps.mPermissions != mDefaultFilterOps.mPermissions
|
||||
|| mFilterOps.mMinDate != mDefaultFilterOps.mMinDate
|
||||
|| mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate
|
||||
|| mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo;
|
||||
BOOL not_default = FALSE;
|
||||
|
||||
not_default |= (mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes);
|
||||
not_default |= (mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes);
|
||||
not_default |= (mFilterOps.mFilterWearableTypes != mDefaultFilterOps.mFilterWearableTypes);
|
||||
not_default |= (mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes);
|
||||
not_default |= (mFilterOps.mFilterLinks != mDefaultFilterOps.mFilterLinks);
|
||||
not_default |= (mFilterSubString.size());
|
||||
not_default |= (mFilterOps.mFilterWorn != mDefaultFilterOps.mFilterWorn);
|
||||
not_default |= (mFilterOps.mPermissions != mDefaultFilterOps.mPermissions);
|
||||
not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate);
|
||||
not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate);
|
||||
not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo);
|
||||
|
||||
return not_default;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::isActive() const
|
||||
{
|
||||
return mFilterOps.mFilterTypes != 0xffffffff
|
||||
return mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL
|
||||
|| mFilterOps.mFilterCategoryTypes != 0xffffffffffffffffULL
|
||||
|| mFilterOps.mFilterWearableTypes != 0xffffffffffffffffULL
|
||||
|| mFilterOps.mFilterTypes != FILTERTYPE_OBJECT
|
||||
|| mFilterOps.mFilterLinks != FILTERLINK_INCLUDE_LINKS
|
||||
|| mFilterSubString.size()
|
||||
|| mFilterWorn
|
||||
|| mFilterOps.mFilterWorn != false
|
||||
|| mFilterOps.mPermissions != PERM_NONE
|
||||
|| mFilterOps.mMinDate != time_min()
|
||||
|| mFilterOps.mMaxDate != time_max()
|
||||
@@ -157,15 +325,15 @@ BOOL LLInventoryFilter::isModifiedAndClear()
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterTypes(U32 types)
|
||||
void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
|
||||
{
|
||||
if (mFilterOps.mFilterTypes != types)
|
||||
if (current_types != types)
|
||||
{
|
||||
// keep current items only if no type bits getting turned off
|
||||
BOOL fewer_bits_set = (mFilterOps.mFilterTypes & ~types);
|
||||
BOOL more_bits_set = (~mFilterOps.mFilterTypes & types);
|
||||
|
||||
mFilterOps.mFilterTypes = types;
|
||||
bool fewer_bits_set = (current_types & ~types) != 0;
|
||||
bool more_bits_set = (~current_types & types) != 0;
|
||||
|
||||
current_types = types;
|
||||
if (more_bits_set && fewer_bits_set)
|
||||
{
|
||||
// neither less or more restrive, both simultaneously
|
||||
@@ -181,10 +349,46 @@ void LLInventoryFilter::setFilterTypes(U32 types)
|
||||
{
|
||||
setModified(FILTER_MORE_RESTRICTIVE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterObjectTypes(U64 types)
|
||||
{
|
||||
updateFilterTypes(types, mFilterOps.mFilterObjectTypes);
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterCategoryTypes(U64 types)
|
||||
{
|
||||
updateFilterTypes(types, mFilterOps.mFilterCategoryTypes);
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_CATEGORY;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterWearableTypes(U64 types)
|
||||
{
|
||||
updateFilterTypes(types, mFilterOps.mFilterWearableTypes);
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_WEARABLE;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterEmptySystemFolders()
|
||||
{
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_EMPTYFOLDERS;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterUUID(const LLUUID& object_id)
|
||||
{
|
||||
if (mFilterOps.mFilterUUID == LLUUID::null)
|
||||
{
|
||||
setModified(FILTER_MORE_RESTRICTIVE);
|
||||
}
|
||||
else
|
||||
{
|
||||
setModified(FILTER_RESTART);
|
||||
}
|
||||
mFilterOps.mFilterUUID = object_id;
|
||||
mFilterOps.mFilterTypes = FILTERTYPE_UUID;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterSubString(const std::string& string)
|
||||
{
|
||||
std::string filter_sub_string_new = string;
|
||||
@@ -215,6 +419,20 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
|
||||
{
|
||||
setModified(FILTER_RESTART);
|
||||
}
|
||||
|
||||
// Cancel out UUID once the search string is modified
|
||||
if (mFilterOps.mFilterTypes == FILTERTYPE_UUID)
|
||||
{
|
||||
mFilterOps.mFilterTypes &= ~FILTERTYPE_UUID;
|
||||
mFilterOps.mFilterUUID == LLUUID::null;
|
||||
setModified(FILTER_RESTART);
|
||||
}
|
||||
|
||||
// Cancel out filter links once the search string is modified
|
||||
// Singu Note: No, don't do this...
|
||||
{
|
||||
//mFilterOps.mFilterLinks = FILTERLINK_INCLUDE_LINKS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -256,6 +474,7 @@ void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date)
|
||||
mFilterOps.mMaxDate = llmax(mFilterOps.mMinDate, max_date);
|
||||
setModified();
|
||||
}
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
|
||||
@@ -270,12 +489,18 @@ void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
|
||||
setDateRange(0, time_max());
|
||||
setModified();
|
||||
}
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::isSinceLogoff() const
|
||||
{
|
||||
return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
|
||||
(mFilterOps.mMaxDate == time_max());
|
||||
bool min_date = (mFilterOps.mMinDate == (time_t)mLastLogoff);
|
||||
bool max_date = (mFilterOps.mMaxDate == time_max());
|
||||
bool is_filter = (mFilterOps.mFilterTypes & FILTERTYPE_DATE);
|
||||
return min_date && max_date && is_filter;
|
||||
//return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
|
||||
// (mFilterOps.mMaxDate == time_max()) &&
|
||||
// (mFilterOps.mFilterTypes & FILTERTYPE_DATE);
|
||||
}
|
||||
|
||||
void LLInventoryFilter::clearModified()
|
||||
@@ -313,7 +538,22 @@ void LLInventoryFilter::setHoursAgo(U32 hours)
|
||||
setModified(FILTER_RESTART);
|
||||
}
|
||||
}
|
||||
mFilterOps.mFilterTypes |= FILTERTYPE_DATE;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setFilterLinks(U64 filter_links)
|
||||
{
|
||||
if (mFilterOps.mFilterLinks != filter_links)
|
||||
{
|
||||
if (mFilterOps.mFilterLinks == FILTERLINK_EXCLUDE_LINKS ||
|
||||
mFilterOps.mFilterLinks == FILTERLINK_ONLY_LINKS)
|
||||
setModified(FILTER_MORE_RESTRICTIVE);
|
||||
else
|
||||
setModified(FILTER_LESS_RESTRICTIVE);
|
||||
}
|
||||
mFilterOps.mFilterLinks = filter_links;
|
||||
}
|
||||
|
||||
void LLInventoryFilter::setShowFolderState(EFolderShow state)
|
||||
{
|
||||
if (mFilterOps.mShowFolderState != state)
|
||||
@@ -403,9 +643,9 @@ void LLInventoryFilter::setModified(EFilterBehavior behavior)
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::isFilterWith(LLInventoryType::EType t) const
|
||||
BOOL LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const
|
||||
{
|
||||
return mFilterOps.mFilterTypes & (0x01 << t);
|
||||
return mFilterOps.mFilterObjectTypes & (1LL << t);
|
||||
}
|
||||
|
||||
const std::string& LLInventoryFilter::getFilterText()
|
||||
@@ -423,7 +663,7 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
S32 num_filter_types = 0;
|
||||
mFilterText.clear();
|
||||
|
||||
if (isFilterWith(LLInventoryType::IT_ANIMATION))
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_ANIMATION))
|
||||
{
|
||||
filtered_types += " Animations,";
|
||||
filtered_by_type = TRUE;
|
||||
@@ -435,7 +675,7 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (isFilterWith(LLInventoryType::IT_CALLINGCARD))
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_CALLINGCARD))
|
||||
{
|
||||
filtered_types += " Calling Cards,";
|
||||
filtered_by_type = TRUE;
|
||||
@@ -447,7 +687,7 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (isFilterWith(LLInventoryType::IT_WEARABLE))
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_WEARABLE))
|
||||
{
|
||||
filtered_types += " Clothing,";
|
||||
filtered_by_type = TRUE;
|
||||
@@ -459,7 +699,7 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (isFilterWith(LLInventoryType::IT_GESTURE))
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_GESTURE))
|
||||
{
|
||||
filtered_types += " Gestures,";
|
||||
filtered_by_type = TRUE;
|
||||
@@ -471,7 +711,7 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (isFilterWith(LLInventoryType::IT_LANDMARK))
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_LANDMARK))
|
||||
{
|
||||
filtered_types += " Landmarks,";
|
||||
filtered_by_type = TRUE;
|
||||
@@ -483,7 +723,7 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (isFilterWith(LLInventoryType::IT_NOTECARD))
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD))
|
||||
{
|
||||
filtered_types += " Notecards,";
|
||||
filtered_by_type = TRUE;
|
||||
@@ -495,7 +735,7 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (isFilterWith(LLInventoryType::IT_OBJECT) && isFilterWith(LLInventoryType::IT_ATTACHMENT))
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_OBJECT) && isFilterObjectTypesWith(LLInventoryType::IT_ATTACHMENT))
|
||||
{
|
||||
filtered_types += " Objects,";
|
||||
filtered_by_type = TRUE;
|
||||
@@ -507,7 +747,7 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (isFilterWith(LLInventoryType::IT_LSL))
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_LSL))
|
||||
{
|
||||
filtered_types += " Scripts,";
|
||||
filtered_by_type = TRUE;
|
||||
@@ -519,7 +759,7 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (isFilterWith(LLInventoryType::IT_SOUND))
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_SOUND))
|
||||
{
|
||||
filtered_types += " Sounds,";
|
||||
filtered_by_type = TRUE;
|
||||
@@ -531,7 +771,7 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (isFilterWith(LLInventoryType::IT_TEXTURE))
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_TEXTURE))
|
||||
{
|
||||
filtered_types += " Textures,";
|
||||
filtered_by_type = TRUE;
|
||||
@@ -543,7 +783,7 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
filtered_by_all_types = FALSE;
|
||||
}
|
||||
|
||||
if (isFilterWith(LLInventoryType::IT_SNAPSHOT))
|
||||
if (isFilterObjectTypesWith(LLInventoryType::IT_SNAPSHOT))
|
||||
{
|
||||
filtered_types += " Snapshots,";
|
||||
filtered_by_type = TRUE;
|
||||
@@ -588,7 +828,7 @@ const std::string& LLInventoryFilter::getFilterText()
|
||||
|
||||
void LLInventoryFilter::toLLSD(LLSD& data) const
|
||||
{
|
||||
data["filter_types"] = (LLSD::Integer)getFilterTypes();
|
||||
data["filter_types"] = (LLSD::Integer)getFilterObjectTypes();
|
||||
data["min_date"] = (LLSD::Integer)getMinDate();
|
||||
data["max_date"] = (LLSD::Integer)getMaxDate();
|
||||
data["hours_ago"] = (LLSD::Integer)getHoursAgo();
|
||||
@@ -603,7 +843,7 @@ void LLInventoryFilter::fromLLSD(LLSD& data)
|
||||
{
|
||||
if(data.has("filter_types"))
|
||||
{
|
||||
setFilterTypes((U32)data["filter_types"].asInteger());
|
||||
setFilterObjectTypes((U32)data["filter_types"].asInteger());
|
||||
}
|
||||
|
||||
if(data.has("min_date") && data.has("max_date"))
|
||||
@@ -642,6 +882,16 @@ void LLInventoryFilter::fromLLSD(LLSD& data)
|
||||
}
|
||||
}
|
||||
|
||||
U64 LLInventoryFilter::getFilterObjectTypes() const
|
||||
{
|
||||
return mFilterOps.mFilterObjectTypes;
|
||||
}
|
||||
|
||||
U64 LLInventoryFilter::getFilterCategoryTypes() const
|
||||
{
|
||||
return mFilterOps.mFilterCategoryTypes;
|
||||
}
|
||||
|
||||
BOOL LLInventoryFilter::hasFilterString() const
|
||||
{
|
||||
return mFilterSubString.size() > 0;
|
||||
@@ -665,6 +915,10 @@ U32 LLInventoryFilter::getHoursAgo() const
|
||||
{
|
||||
return mFilterOps.mHoursAgo;
|
||||
}
|
||||
U64 LLInventoryFilter::getFilterLinks() const
|
||||
{
|
||||
return mFilterOps.mFilterLinks;
|
||||
}
|
||||
LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const
|
||||
{
|
||||
return mFilterOps.mShowFolderState;
|
||||
|
||||
@@ -51,8 +51,26 @@ public:
|
||||
FILTER_MORE_RESTRICTIVE // if you didn't pass the previous filter, you definitely won't pass this one
|
||||
};
|
||||
|
||||
enum EFilterType {
|
||||
FILTERTYPE_NONE = 0,
|
||||
FILTERTYPE_OBJECT = 0x1 << 0, // normal default search-by-object-type
|
||||
FILTERTYPE_CATEGORY = 0x1 << 1, // search by folder type
|
||||
FILTERTYPE_UUID = 0x1 << 2, // find the object with UUID and any links to it
|
||||
FILTERTYPE_DATE = 0x1 << 3, // search by date range
|
||||
FILTERTYPE_WEARABLE = 0x1 << 4, // search by wearable type
|
||||
FILTERTYPE_EMPTYFOLDERS = 0x1 << 5 // pass if folder is not a system folder to be hidden if empty
|
||||
};
|
||||
|
||||
enum EFilterLink
|
||||
{
|
||||
FILTERLINK_INCLUDE_LINKS, // show links too
|
||||
FILTERLINK_EXCLUDE_LINKS, // don't show links
|
||||
FILTERLINK_ONLY_LINKS // only show links
|
||||
};
|
||||
|
||||
enum ESortOrderType
|
||||
{
|
||||
SO_NAME = 0, // Sort inventory by name
|
||||
SO_DATE = 0x1, // Sort inventory by date
|
||||
SO_FOLDERS_BY_NAME = 0x1 << 1, // Force folder sort by name
|
||||
SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2 // Force system folders to be on top
|
||||
@@ -61,17 +79,26 @@ public:
|
||||
LLInventoryFilter(const std::string& name);
|
||||
virtual ~LLInventoryFilter();
|
||||
|
||||
void setFilterTypes(U32 types);
|
||||
BOOL isFilterWith(LLInventoryType::EType t) const;
|
||||
U32 getFilterTypes() const { return mFilterOps.mFilterTypes; }
|
||||
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Parameters
|
||||
// +-------------------------------------------------------------------+
|
||||
void setFilterObjectTypes(U64 types);
|
||||
U64 getFilterObjectTypes() const;
|
||||
U64 getFilterCategoryTypes() const;
|
||||
BOOL isFilterObjectTypesWith(LLInventoryType::EType t) const;
|
||||
void setFilterCategoryTypes(U64 types);
|
||||
void setFilterUUID(const LLUUID &object_id);
|
||||
void setFilterWearableTypes(U64 types);
|
||||
void setFilterEmptySystemFolders();
|
||||
void updateFilterTypes(U64 types, U64& current_types);
|
||||
|
||||
void setFilterSubString(const std::string& string);
|
||||
const std::string& getFilterSubString(BOOL trim = FALSE) const;
|
||||
const std::string& getFilterSubStringOrig() const { return mFilterSubStringOrig; }
|
||||
BOOL hasFilterString() const;
|
||||
|
||||
void setFilterWorn(bool worn) { mFilterWorn = worn; }
|
||||
bool getFilterWorn() const { return mFilterWorn; }
|
||||
void setFilterWorn(bool worn) { mFilterOps.mFilterWorn = worn; }
|
||||
bool getFilterWorn() const { return mFilterOps.mFilterWorn; }
|
||||
|
||||
void setFilterPermissions(PermissionMask perms);
|
||||
PermissionMask getFilterPermissions() const;
|
||||
@@ -84,10 +111,18 @@ public:
|
||||
void setHoursAgo(U32 hours);
|
||||
U32 getHoursAgo() const;
|
||||
|
||||
void setFilterLinks(U64 filter_link);
|
||||
U64 getFilterLinks() const;
|
||||
|
||||
// +-------------------------------------------------------------------+
|
||||
// + Execution And Results
|
||||
// +-------------------------------------------------------------------+
|
||||
BOOL check(LLFolderViewItem* item);
|
||||
BOOL check(LLFolderViewItem* item);
|
||||
bool checkFolder(const LLFolderViewFolder* folder);
|
||||
BOOL checkAgainstFilterType(const LLFolderViewItem* item) const;
|
||||
BOOL checkAgainstPermissions(const LLFolderViewItem* item) const;
|
||||
BOOL checkAgainstFilterLinks(const LLFolderViewItem* item) const;
|
||||
|
||||
std::string::size_type getStringMatchOffset() const;
|
||||
|
||||
// +-------------------------------------------------------------------+
|
||||
@@ -146,12 +181,20 @@ private:
|
||||
struct FilterOps
|
||||
{
|
||||
FilterOps();
|
||||
U32 mFilterTypes;
|
||||
U32 mFilterTypes;
|
||||
|
||||
U64 mFilterObjectTypes; // For _OBJECT
|
||||
U64 mFilterWearableTypes;
|
||||
U64 mFilterCategoryTypes; // For _CATEGORY
|
||||
LLUUID mFilterUUID; // for UUID
|
||||
|
||||
time_t mMinDate;
|
||||
time_t mMaxDate;
|
||||
U32 mHoursAgo;
|
||||
EFolderShow mShowFolderState;
|
||||
PermissionMask mPermissions;
|
||||
U64 mFilterLinks;
|
||||
bool mFilterWorn;
|
||||
};
|
||||
|
||||
U32 mOrder;
|
||||
@@ -163,21 +206,19 @@ private:
|
||||
std::string::size_type mSubStringMatchOffset;
|
||||
std::string mFilterSubString;
|
||||
std::string mFilterSubStringOrig;
|
||||
bool mFilterWorn;
|
||||
|
||||
const std::string mName;
|
||||
S32 mFilterGeneration;
|
||||
S32 mMustPassGeneration;
|
||||
S32 mMinRequiredGeneration;
|
||||
S32 mNextFilterGeneration;
|
||||
const std::string mName;
|
||||
|
||||
S32 mFilterCount;
|
||||
EFilterBehavior mFilterBehavior;
|
||||
S32 mFilterGeneration;
|
||||
S32 mMustPassGeneration;
|
||||
S32 mMinRequiredGeneration;
|
||||
S32 mNextFilterGeneration;
|
||||
|
||||
BOOL mModified;
|
||||
BOOL mNeedTextRebuild;
|
||||
std::string mFilterText;
|
||||
S32 mFilterCount;
|
||||
EFilterBehavior mFilterBehavior;
|
||||
|
||||
BOOL mModified;
|
||||
BOOL mNeedTextRebuild;
|
||||
std::string mFilterText;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "message.h"
|
||||
|
||||
// newview includes
|
||||
#include "llappearancemgr.h"
|
||||
#include "llappviewer.h"
|
||||
//#include "llfirstuse.h"
|
||||
#include "llfloaterinventory.h"
|
||||
@@ -52,9 +53,11 @@
|
||||
#include "llinventorybridge.h"
|
||||
#include "llinventoryclipboard.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llmenugl.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llpanelmaininventory.h"
|
||||
#include "llpreviewanim.h"
|
||||
#include "llpreviewgesture.h"
|
||||
#include "llpreviewnotecard.h"
|
||||
@@ -75,13 +78,13 @@
|
||||
#include "llvoavatarself.h"
|
||||
#include "llwearablelist.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
|
||||
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
|
||||
#include "rlvhandler.h"
|
||||
#include "rlvlocks.h"
|
||||
// [/RLVa:KB]
|
||||
|
||||
#include "cofmgr.h"
|
||||
|
||||
BOOL LLInventoryState::sWearNewClothing = FALSE;
|
||||
LLUUID LLInventoryState::sWearNewClothingTransactionID;
|
||||
|
||||
@@ -164,7 +167,7 @@ void change_category_parent(LLInventoryModel* model,
|
||||
model->notifyObservers();
|
||||
}
|
||||
|
||||
/*void remove_category(LLInventoryModel* model, const LLUUID& cat_id)
|
||||
void remove_category(LLInventoryModel* model, const LLUUID& cat_id)
|
||||
{
|
||||
if (!model || !get_is_category_removable(model, cat_id))
|
||||
{
|
||||
@@ -195,7 +198,7 @@ void change_category_parent(LLInventoryModel* model,
|
||||
const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
|
||||
change_category_parent(model, cat, trash_id, TRUE);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void rename_category(LLInventoryModel* model, const LLUUID& cat_id, const std::string& new_name)
|
||||
{
|
||||
@@ -237,7 +240,7 @@ BOOL get_is_parent_to_worn_item(const LLUUID& id)
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLInventoryModel::item_array_t items;
|
||||
LLInventoryCollectAllItems collect_all;
|
||||
gInventory.collectDescendentsIf(LLCOFMgr::instance().getCOF(), cats, items, LLInventoryModel::EXCLUDE_TRASH, collect_all);
|
||||
gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(), cats, items, LLInventoryModel::EXCLUDE_TRASH, collect_all);
|
||||
|
||||
for (LLInventoryModel::item_array_t::const_iterator it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
@@ -313,13 +316,13 @@ BOOL get_can_item_be_worn(const LLUUID& id)
|
||||
if (!item)
|
||||
return FALSE;
|
||||
|
||||
if (LLCOFMgr::instance().isLinkInCOF(item->getLinkedUUID()))
|
||||
if (LLAppearanceMgr::isLinkInCOF(item->getLinkedUUID()))
|
||||
{
|
||||
// an item having links in COF (i.e. a worn item)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (gInventory.isObjectDescendentOf(id, LLCOFMgr::instance().getCOF()))
|
||||
if (gInventory.isObjectDescendentOf(id, LLAppearanceMgr::instance().getCOF()))
|
||||
{
|
||||
// a non-link object in COF (should not normally happen)
|
||||
return FALSE;
|
||||
@@ -363,12 +366,10 @@ BOOL get_can_item_be_worn(const LLUUID& id)
|
||||
// Not being worn yet.
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -379,6 +380,11 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if(id == gInventory.getRootFolderID())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Can't delete an item that's in the library.
|
||||
if(!model->isObjectDescendentOf(id, gInventory.getRootFolderID()))
|
||||
{
|
||||
@@ -387,7 +393,7 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
|
||||
// Disable delete from COF folder; have users explicitly choose "detach/take off",
|
||||
// unless the item is not worn but in the COF (i.e. is bugged).
|
||||
if (LLCOFMgr::instance().getIsProtectedCOFItem(id))
|
||||
if (LLAppearanceMgr::instance().getIsProtectedCOFItem(id))
|
||||
{
|
||||
if (get_is_item_worn(id))
|
||||
{
|
||||
@@ -415,7 +421,7 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
{
|
||||
// NOTE: This function doesn't check the folder's children.
|
||||
// See LLFolderBridge::isItemRemovable for a function that does
|
||||
@@ -465,7 +471,7 @@ BOOL get_is_item_removable(const LLInventoryModel* model, const LLUUID& id)
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}*/
|
||||
}
|
||||
|
||||
BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)
|
||||
{
|
||||
@@ -492,6 +498,26 @@ BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id)
|
||||
}
|
||||
|
||||
|
||||
void show_item_profile(const LLUUID& item_uuid)
|
||||
{
|
||||
LLUUID linked_uuid = gInventory.getLinkedItemID(item_uuid);
|
||||
if(!LLFloaterProperties::show(linked_uuid, LLUUID::null))
|
||||
{
|
||||
S32 left, top;
|
||||
gFloaterView->getNewFloaterPosition(&left, &top);
|
||||
LLRect rect = gSavedSettings.getRect("PropertiesRect");
|
||||
rect.translate( left - rect.mLeft, top - rect.mTop );
|
||||
LLFloaterProperties* floater;
|
||||
floater = new LLFloaterProperties("item properties",
|
||||
rect,
|
||||
"Inventory Item Properties",
|
||||
linked_uuid,
|
||||
LLUUID::null);
|
||||
// keep onscreen
|
||||
gFloaterView->adjustToFitScreen(floater, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// LLInventoryCollectFunctor implementations
|
||||
///----------------------------------------------------------------------------
|
||||
@@ -641,6 +667,33 @@ bool LLNameCategoryCollector::operator()(
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLFindCOFValidItems::operator()(LLInventoryCategory* cat,
|
||||
LLInventoryItem* item)
|
||||
{
|
||||
// Valid COF items are:
|
||||
// - links to wearables (body parts or clothing)
|
||||
// - links to attachments
|
||||
// - links to gestures
|
||||
// - links to ensemble folders
|
||||
LLViewerInventoryItem *linked_item = ((LLViewerInventoryItem*)item)->getLinkedItem();
|
||||
if (linked_item)
|
||||
{
|
||||
LLAssetType::EType type = linked_item->getType();
|
||||
return (type == LLAssetType::AT_CLOTHING ||
|
||||
type == LLAssetType::AT_BODYPART ||
|
||||
type == LLAssetType::AT_GESTURE ||
|
||||
type == LLAssetType::AT_OBJECT);
|
||||
}
|
||||
else
|
||||
{
|
||||
LLViewerInventoryCategory *linked_category = ((LLViewerInventoryItem*)item)->getLinkedCategory();
|
||||
// BAP remove AT_NONE support after ensembles are fully working?
|
||||
return (linked_category &&
|
||||
((linked_category->getPreferredType() == LLFolderType::FT_NONE) ||
|
||||
(LLFolderType::lookupIsEnsembleType(linked_category->getPreferredType()))));
|
||||
}
|
||||
}
|
||||
|
||||
bool LLFindWearables::operator()(LLInventoryCategory* cat,
|
||||
LLInventoryItem* item)
|
||||
{
|
||||
@@ -686,6 +739,40 @@ bool LLFindWearablesEx::operator()(LLInventoryCategory* cat, LLInventoryItem* it
|
||||
return (bool) get_is_item_worn(item->getUUID()) == mIsWorn;
|
||||
}
|
||||
|
||||
bool LLFindWearablesOfType::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
if (!item) return false;
|
||||
if (item->getType() != LLAssetType::AT_CLOTHING &&
|
||||
item->getType() != LLAssetType::AT_BODYPART)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
LLViewerInventoryItem *vitem = dynamic_cast<LLViewerInventoryItem*>(item);
|
||||
if (!vitem || vitem->getWearableType() != mWearableType) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLFindWearablesOfType::setType(LLWearableType::EType type)
|
||||
{
|
||||
mWearableType = type;
|
||||
}
|
||||
|
||||
bool LLFindNonRemovableObjects::operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
if (item)
|
||||
{
|
||||
return !get_is_item_removable(&gInventory, item->getUUID());
|
||||
}
|
||||
if (cat)
|
||||
{
|
||||
return !get_is_category_removable(&gInventory, cat->getUUID());
|
||||
}
|
||||
|
||||
llwarns << "Not a category and not an item?" << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// LLAssetIDMatches
|
||||
|
||||
@@ -53,6 +53,8 @@ BOOL get_is_category_removable(const LLInventoryModel* model, const LLUUID& id);
|
||||
|
||||
BOOL get_is_category_renameable(const LLInventoryModel* model, const LLUUID& id);
|
||||
|
||||
void show_item_profile(const LLUUID& item_uuid);
|
||||
|
||||
void change_item_parent(LLInventoryModel* model,
|
||||
LLViewerInventoryItem* item,
|
||||
const LLUUID& new_parent_id,
|
||||
@@ -262,6 +264,77 @@ protected:
|
||||
std::string mName;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFindCOFValidItems
|
||||
//
|
||||
// Collects items that can be legitimately linked to in the COF.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLFindCOFValidItems : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLFindCOFValidItems() {}
|
||||
virtual ~LLFindCOFValidItems() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat,
|
||||
LLInventoryItem* item);
|
||||
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFindByMask
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLFindByMask : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLFindByMask(U64 mask)
|
||||
: mFilterMask(mask)
|
||||
{}
|
||||
|
||||
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
//converting an inventory type to a bitmap filter mask
|
||||
if(item && (mFilterMask & (1LL << item->getInventoryType())) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
U64 mFilterMask;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFindNonLinksByMask
|
||||
//
|
||||
//
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLFindNonLinksByMask : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLFindNonLinksByMask(U64 mask)
|
||||
: mFilterMask(mask)
|
||||
{}
|
||||
|
||||
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
if(item && !item->getIsLinkType() && (mFilterMask & (1LL << item->getInventoryType())) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void setFilterMask(U64 mask)
|
||||
{
|
||||
mFilterMask = mask;
|
||||
}
|
||||
|
||||
private:
|
||||
U64 mFilterMask;
|
||||
};
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLFindWearables
|
||||
//
|
||||
@@ -292,6 +365,52 @@ private:
|
||||
bool mIsWorn;
|
||||
};
|
||||
|
||||
//Inventory collect functor collecting wearables of a specific wearable type
|
||||
class LLFindWearablesOfType : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
LLFindWearablesOfType(LLWearableType::EType type) : mWearableType(type) {}
|
||||
virtual ~LLFindWearablesOfType() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
|
||||
void setType(LLWearableType::EType type);
|
||||
|
||||
private:
|
||||
LLWearableType::EType mWearableType;
|
||||
};
|
||||
|
||||
/** Filter out wearables-links */
|
||||
class LLFindActualWearablesOfType : public LLFindWearablesOfType
|
||||
{
|
||||
public:
|
||||
LLFindActualWearablesOfType(LLWearableType::EType type) : LLFindWearablesOfType(type) {}
|
||||
virtual ~LLFindActualWearablesOfType() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
if (item && item->getIsLinkType()) return false;
|
||||
return LLFindWearablesOfType::operator()(cat, item);
|
||||
}
|
||||
};
|
||||
|
||||
/* Filters out items of a particular asset type */
|
||||
class LLIsTypeActual : public LLIsType
|
||||
{
|
||||
public:
|
||||
LLIsTypeActual(LLAssetType::EType type) : LLIsType(type) {}
|
||||
virtual ~LLIsTypeActual() {}
|
||||
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
|
||||
{
|
||||
if (item && item->getIsLinkType()) return false;
|
||||
return LLIsType::operator()(cat, item);
|
||||
}
|
||||
};
|
||||
|
||||
// Collect non-removable folders and items.
|
||||
class LLFindNonRemovableObjects : public LLInventoryCollectFunctor
|
||||
{
|
||||
public:
|
||||
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item);
|
||||
};
|
||||
|
||||
/** Inventory Collector Functions
|
||||
** **
|
||||
*******************************************************************************/
|
||||
|
||||
@@ -2,73 +2,51 @@
|
||||
* @file llinventorymodel.cpp
|
||||
* @brief Implementation of the inventory model used to track agent inventory.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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 "llinventorymodel.h"
|
||||
|
||||
#include "llassetstorage.h"
|
||||
#include "llcrc.h"
|
||||
#include "lldir.h"
|
||||
#include "llsys.h"
|
||||
#include "llxfermanager.h"
|
||||
#include "llagent.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "llinventorybridge.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventoryobserver.h"
|
||||
#include "message.h"
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llfloater.h"
|
||||
#include "llfloaterinventory.h"
|
||||
#include "llfocusmgr.h"
|
||||
#include "llinventorypanel.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llwindow.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llpreview.h"
|
||||
#include "llviewermessage.h"
|
||||
#include "llfoldertype.h"
|
||||
#include "llviewerfoldertype.h"
|
||||
#include "llviewerwindow.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llappviewer.h"
|
||||
#include "lldbstrings.h"
|
||||
#include "llviewerstats.h"
|
||||
#include "llmutelist.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llcallbacklist.h"
|
||||
#include "llpreview.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llvoavatarself.h"
|
||||
#include "statemachine/aievent.h"
|
||||
// <edit>
|
||||
#include "llappviewer.h" // gLostItemsRoot
|
||||
// </edit>
|
||||
#include <deque>
|
||||
|
||||
// [RLVa:KB]
|
||||
#include "rlvhandler.h"
|
||||
@@ -82,6 +60,7 @@
|
||||
// Increment this if the inventory contents change in a non-backwards-compatible way.
|
||||
// For viewers with link items support, former caches are incorrect.
|
||||
const S32 LLInventoryModel::sCurrentInvCacheVersion = 2;
|
||||
BOOL LLInventoryModel::sFirstTimeInViewer2 = TRUE;
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function declarations, constants, enums, and typedefs
|
||||
@@ -262,6 +241,38 @@ const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(cons
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//
|
||||
// Search up the parent chain until we get to the specified parent, then return the first child category under it
|
||||
//
|
||||
const LLViewerInventoryCategory* LLInventoryModel::getFirstDescendantOf(const LLUUID& master_parent_id, const LLUUID& obj_id) const
|
||||
{
|
||||
if (master_parent_id == obj_id)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const LLViewerInventoryCategory* current_cat = getCategory(obj_id);
|
||||
|
||||
if (current_cat == NULL)
|
||||
{
|
||||
current_cat = getCategory(getObject(obj_id)->getParentUUID());
|
||||
}
|
||||
|
||||
while (current_cat != NULL)
|
||||
{
|
||||
const LLUUID& current_parent_id = current_cat->getParentUUID();
|
||||
|
||||
if (current_parent_id == master_parent_id)
|
||||
{
|
||||
return current_cat;
|
||||
}
|
||||
|
||||
current_cat = getCategory(current_parent_id);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the object by id. Returns NULL if not found.
|
||||
LLInventoryObject* LLInventoryModel::getObject(const LLUUID& id) const
|
||||
{
|
||||
@@ -1109,6 +1120,7 @@ void LLInventoryModel::deleteObject(const LLUUID& id)
|
||||
}
|
||||
addChangedMask(LLInventoryObserver::REMOVE, id);
|
||||
obj = NULL; // delete obj
|
||||
updateLinkedObjectsFromPurge(id);
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
|
||||
@@ -1125,6 +1137,25 @@ void LLInventoryModel::purgeObject(const LLUUID &id)
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id)
|
||||
{
|
||||
LLInventoryModel::item_array_t item_array = collectLinkedItems(baseobj_id);
|
||||
|
||||
// REBUILD is expensive, so clear the current change list first else
|
||||
// everything else on the changelist will also get rebuilt.
|
||||
gInventory.notifyObservers();
|
||||
for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
|
||||
iter != item_array.end();
|
||||
iter++)
|
||||
{
|
||||
const LLViewerInventoryItem *linked_item = (*iter);
|
||||
const LLUUID &item_id = linked_item->getUUID();
|
||||
if (item_id == baseobj_id) continue;
|
||||
addChangedMask(LLInventoryObserver::REBUILD, item_id);
|
||||
}
|
||||
gInventory.notifyObservers();
|
||||
}
|
||||
|
||||
// This is a method which collects the descendents of the id
|
||||
// provided. If the category is not found, no action is
|
||||
// taken. This method goes through the long winded process of
|
||||
@@ -2008,6 +2039,10 @@ void LLInventoryModel::buildParentChildMap()
|
||||
llwarns << "Found " << lost << " lost categories." << llendl;
|
||||
}
|
||||
|
||||
const BOOL COF_exists = (findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, FALSE) != LLUUID::null);
|
||||
sFirstTimeInViewer2 = !COF_exists || gAgent.isFirstLogin();
|
||||
|
||||
|
||||
// Now the items. We allocated in the last step, so now all we
|
||||
// have to do is iterate over the items and put them in the right
|
||||
// place.
|
||||
@@ -2614,10 +2649,10 @@ void LLInventoryModel::processUpdateInventoryFolder(LLMessageSystem* msg,
|
||||
gInventory.notifyObservers();
|
||||
|
||||
// *HACK: Do the 'show' logic for a new item in the inventory.
|
||||
LLInventoryView* view = LLInventoryView::getActiveInventory();
|
||||
if(view)
|
||||
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
|
||||
if (active_panel)
|
||||
{
|
||||
view->getPanel()->setSelection(lastfolder->getUUID(), TAKE_FOCUS_NO);
|
||||
active_panel->setSelection(lastfolder->getUUID(), TAKE_FOCUS_NO);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2888,7 +2923,7 @@ void LLInventoryModel::processBulkUpdateInventory(LLMessageSystem* msg, void**)
|
||||
{
|
||||
LLViewerInventoryItem* wearable_item;
|
||||
wearable_item = gInventory.getItem(wearable_ids[i]);
|
||||
wear_inventory_item_on_avatar(wearable_item);
|
||||
LLAppearanceMgr::instance().wearItemOnAvatar(wearable_item->getUUID(), true, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3112,6 +3147,139 @@ void LLInventoryModel::setLibraryOwnerID(const LLUUID& val)
|
||||
mLibraryOwnerID = val;
|
||||
}
|
||||
|
||||
// static
|
||||
BOOL LLInventoryModel::getIsFirstTimeInViewer2()
|
||||
{
|
||||
// Do not call this before parentchild map is built.
|
||||
if (!gInventory.mIsAgentInvUsable)
|
||||
{
|
||||
llwarns << "Parent Child Map not yet built; guessing as first time in viewer2." << llendl;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return sFirstTimeInViewer2;
|
||||
}
|
||||
|
||||
LLInventoryModel::item_array_t::iterator LLInventoryModel::findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id)
|
||||
{
|
||||
LLInventoryModel::item_array_t::iterator curr_item = items.begin();
|
||||
|
||||
while (curr_item != items.end())
|
||||
{
|
||||
if ((*curr_item)->getUUID() == id)
|
||||
{
|
||||
break;
|
||||
}
|
||||
++curr_item;
|
||||
}
|
||||
|
||||
return curr_item;
|
||||
}
|
||||
|
||||
// static
|
||||
// * @param[in, out] items - vector with items to be updated. It should be sorted in a right way
|
||||
// * before calling this method.
|
||||
// * @param src_item_id - LLUUID of inventory item to be moved in new position
|
||||
// * @param dest_item_id - LLUUID of inventory item before (or after) which source item should
|
||||
// * be placed.
|
||||
// * @param insert_before - bool indicating if src_item_id should be placed before or after
|
||||
// * dest_item_id. Default is true.
|
||||
void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, const LLUUID& src_item_id, const LLUUID& dest_item_id, bool insert_before)
|
||||
{
|
||||
LLInventoryModel::item_array_t::iterator it_src = findItemIterByUUID(items, src_item_id);
|
||||
LLInventoryModel::item_array_t::iterator it_dest = findItemIterByUUID(items, dest_item_id);
|
||||
|
||||
// If one of the passed UUID is not in the item list, bail out
|
||||
if ((it_src == items.end()) || (it_dest == items.end()))
|
||||
return;
|
||||
|
||||
// Erase the source element from the list, keep a copy before erasing.
|
||||
LLViewerInventoryItem* src_item = *it_src;
|
||||
items.erase(it_src);
|
||||
|
||||
// Note: Target iterator is not valid anymore because the container was changed, so update it.
|
||||
it_dest = findItemIterByUUID(items, dest_item_id);
|
||||
|
||||
// Go to the next element if one wishes to insert after the dest element
|
||||
if (!insert_before)
|
||||
{
|
||||
++it_dest;
|
||||
}
|
||||
|
||||
// Reinsert the source item in the right place
|
||||
if (it_dest != items.end())
|
||||
{
|
||||
items.insert(it_dest, src_item);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Append to the list if it_dest reached the end
|
||||
items.push_back(src_item);
|
||||
}
|
||||
}
|
||||
|
||||
//* @param[in] items vector of items in order to be saved.
|
||||
/*void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& items)
|
||||
{
|
||||
int sortField = 0;
|
||||
|
||||
// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
|
||||
for (item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
|
||||
{
|
||||
LLViewerInventoryItem* item = *i;
|
||||
|
||||
item->setSortField(++sortField);
|
||||
item->setComplete(TRUE);
|
||||
item->updateServer(FALSE);
|
||||
|
||||
updateItem(item);
|
||||
|
||||
// Tell the parent folder to refresh its sort order.
|
||||
addChangedMask(LLInventoryObserver::SORT, item->getParentUUID());
|
||||
}
|
||||
|
||||
notifyObservers();
|
||||
}*/
|
||||
|
||||
// See also LLInventorySort where landmarks in the Favorites folder are sorted.
|
||||
/*class LLViewerInventoryItemSort
|
||||
{
|
||||
public:
|
||||
bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b)
|
||||
{
|
||||
return a->getSortField() < b->getSortField();
|
||||
}
|
||||
};*/
|
||||
|
||||
/**
|
||||
* Sorts passed items by LLViewerInventoryItem sort field.
|
||||
*
|
||||
* @param[in, out] items - array of items, not sorted.
|
||||
*/
|
||||
/*static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items)
|
||||
{
|
||||
static LLViewerInventoryItemSort sort_functor;
|
||||
std::sort(items.begin(), items.end(), sort_functor);
|
||||
}*/
|
||||
|
||||
// * @param source_item_id - LLUUID of the source item to be moved into new position
|
||||
// * @param target_item_id - LLUUID of the target item before which source item should be placed.
|
||||
/*void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
|
||||
{
|
||||
LLInventoryModel::cat_array_t cats;
|
||||
LLInventoryModel::item_array_t items;
|
||||
LLIsType is_type(LLAssetType::AT_LANDMARK);
|
||||
LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
|
||||
gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
|
||||
|
||||
// ensure items are sorted properly before changing order. EXT-3498
|
||||
rearrange_item_order_by_sort_field(items);
|
||||
|
||||
// update order
|
||||
updateItemsOrder(items, source_item_id, target_item_id);
|
||||
|
||||
saveItemsOrder(items);
|
||||
}*/
|
||||
// *NOTE: DEBUG functionality
|
||||
void LLInventoryModel::dumpInventory() const
|
||||
{
|
||||
|
||||
@@ -2,31 +2,25 @@
|
||||
* @file llinventorymodel.h
|
||||
* @brief LLInventoryModel class header file
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2002-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -36,6 +30,7 @@
|
||||
#include "llassettype.h"
|
||||
#include "llfoldertype.h"
|
||||
#include "lldarray.h"
|
||||
#include "llframetimer.h"
|
||||
#include "llhttpclient.h"
|
||||
#include "lluuid.h"
|
||||
#include "llpermissionsflags.h"
|
||||
@@ -72,7 +67,10 @@ class LLInventoryCollectFunctor;
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
class LLInventoryModel
|
||||
{
|
||||
LOG_CLASS(LLInventoryModel);
|
||||
public:
|
||||
friend class LLInventoryModelFetchDescendentsResponder;
|
||||
|
||||
enum EHasChildren
|
||||
{
|
||||
CHILDREN_NO,
|
||||
@@ -90,8 +88,6 @@ public:
|
||||
fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
|
||||
void result(const LLSD& content);
|
||||
void error(U32 status, const std::string& reason);
|
||||
public:
|
||||
typedef std::vector<LLViewerInventoryCategory*> folder_ref_t;
|
||||
protected:
|
||||
LLSD mRequestSD;
|
||||
};
|
||||
@@ -168,6 +164,10 @@ private:
|
||||
//--------------------------------------------------------------------
|
||||
// Login
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
static BOOL getIsFirstTimeInViewer2();
|
||||
private:
|
||||
static BOOL sFirstTimeInViewer2;
|
||||
const static S32 sCurrentInvCacheVersion; // expected inventory cache version
|
||||
|
||||
/** Initialization/Setup
|
||||
@@ -247,6 +247,9 @@ public:
|
||||
|
||||
// Get whatever special folder this object is a child of, if any.
|
||||
const LLViewerInventoryCategory *getFirstNondefaultParent(const LLUUID& obj_id) const;
|
||||
|
||||
// Get first descendant of the child object under the specified parent
|
||||
const LLViewerInventoryCategory *getFirstDescendantOf(const LLUUID& master_parent_id, const LLUUID& obj_id) const;
|
||||
|
||||
// Get the object by id. Returns NULL if not found.
|
||||
// NOTE: Use the pointer returned for read operations - do
|
||||
@@ -335,28 +338,33 @@ public:
|
||||
// cache accounting in a fairly efficient manner. This method does
|
||||
// not notify observers (though maybe it should...)
|
||||
void purgeDescendentsOf(const LLUUID& id);
|
||||
|
||||
// This method optimally removes the referenced categories and
|
||||
// items from the current agent's inventory in the database. It
|
||||
// performs all of the during deletion. The local representation
|
||||
// is not removed.
|
||||
void deleteFromServer(LLDynamicArray<LLUUID>& category_ids,
|
||||
LLDynamicArray<LLUUID>& item_ids);
|
||||
|
||||
//
|
||||
// Misc Methods
|
||||
//
|
||||
|
||||
|
||||
// This method to prepares a set of mock inventory which provides
|
||||
// minimal functionality before the actual arrival of inventory.
|
||||
//void mock(const LLUUID& root_id);
|
||||
|
||||
protected:
|
||||
void updateLinkedObjectsFromPurge(const LLUUID& baseobj_id);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Reorder
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
// Changes items order by insertion of the item identified by src_item_id
|
||||
// before (or after) the item identified by dest_item_id. Both items must exist in items array.
|
||||
// Sorting is stored after method is finished. Only src_item_id is moved before (or after) dest_item_id.
|
||||
// The parameter "insert_before" controls on which side of dest_item_id src_item_id gets rensinserted.
|
||||
static void updateItemsOrder(LLInventoryModel::item_array_t& items,
|
||||
const LLUUID& src_item_id,
|
||||
const LLUUID& dest_item_id,
|
||||
bool insert_before = true);
|
||||
// Gets an iterator on an item vector knowing only the item UUID.
|
||||
// Returns end() of the vector if not found.
|
||||
static LLInventoryModel::item_array_t::iterator findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
|
||||
|
||||
// call this method to request the inventory.
|
||||
//void requestFromServer(const LLUUID& agent_id);
|
||||
// Saves current order of the passed items using inventory item sort field.
|
||||
// Resets 'items' sort fields and saves them on server.
|
||||
// Is used to save order for Favorites folder.
|
||||
//void saveItemsOrder(const LLInventoryModel::item_array_t& items);
|
||||
|
||||
// Rearranges Landmarks inside Favorites folder.
|
||||
// Moves source landmark before target one.
|
||||
void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Creation
|
||||
|
||||
@@ -439,6 +439,7 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
|
||||
{
|
||||
cat->setVersion(version);
|
||||
cat->setDescendentCount(descendents);
|
||||
cat->determineFolderType();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -532,7 +533,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch(std::string url)
|
||||
U32 folder_count=0;
|
||||
U32 max_batch_size=5;
|
||||
|
||||
U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1;
|
||||
U32 sort_order = gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER) & 0x1;
|
||||
|
||||
uuid_vec_t recursive_cats;
|
||||
|
||||
|
||||
@@ -56,7 +56,9 @@ public:
|
||||
STRUCTURE = 16, // structural change, eg, item or folder moved
|
||||
CALLING_CARD = 32, // online, grant status, cancel, etc change
|
||||
GESTURE = 64,
|
||||
ALL = 0xffffffff
|
||||
REBUILD = 128, // Item UI changed (e.g. item type different)
|
||||
SORT = 256, // Folder needs to be resorted.
|
||||
ALL = 0xffffffff
|
||||
};
|
||||
LLInventoryObserver();
|
||||
virtual ~LLInventoryObserver();
|
||||
|
||||
@@ -1,32 +1,26 @@
|
||||
/**
|
||||
* @file llinventoryview.cpp
|
||||
* @brief Implementation of the inventory view and associated stuff.
|
||||
/*
|
||||
* @file llinventorypanel.cpp
|
||||
* @brief Implementation of the inventory panel and associated stuff.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2009, Linden Research, Inc.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* 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.
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
* 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.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* 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$
|
||||
*/
|
||||
|
||||
@@ -37,6 +31,7 @@
|
||||
|
||||
#include "llagent.h"
|
||||
#include "llagentwearables.h"
|
||||
#include "llappearancemgr.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llfloatercustomize.h"
|
||||
#include "llfolderview.h"
|
||||
@@ -48,6 +43,7 @@
|
||||
#include "llvoavatarself.h"
|
||||
#include "llscrollcontainer.h"
|
||||
#include "llviewerassettype.h"
|
||||
#include "llpanelmaininventory.h"
|
||||
|
||||
#include "llsdserialize.h"
|
||||
|
||||
@@ -57,12 +53,11 @@
|
||||
|
||||
static LLRegisterWidget<LLInventoryPanel> r("inventory_panel");
|
||||
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function declarations, constants, enums, and typedefs
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder");
|
||||
const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder");
|
||||
const std::string LLInventoryPanel::WORNITEMS_SORT_ORDER = std::string("WornItemsSortOrder");
|
||||
const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
|
||||
static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -88,10 +83,50 @@ protected:
|
||||
|
||||
|
||||
|
||||
const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder");
|
||||
const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder");
|
||||
const std::string LLInventoryPanel::WORNITEMS_SORT_ORDER = std::string("WornItemsSortOrder");
|
||||
const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
|
||||
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLInvPanelComplObserver
|
||||
//
|
||||
// Calls specified callback when all specified items become complete.
|
||||
//
|
||||
// Usage:
|
||||
// observer = new LLInvPanelComplObserver(boost::bind(onComplete));
|
||||
// inventory->addObserver(observer);
|
||||
// observer->reset(); // (optional)
|
||||
// observer->watchItem(incomplete_item1_id);
|
||||
// observer->watchItem(incomplete_item2_id);
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class LLInvPanelComplObserver : public LLInventoryCompletionObserver
|
||||
{
|
||||
public:
|
||||
typedef boost::function<void()> callback_t;
|
||||
|
||||
LLInvPanelComplObserver(callback_t cb)
|
||||
: mCallback(cb)
|
||||
{
|
||||
}
|
||||
|
||||
void reset();
|
||||
|
||||
private:
|
||||
/*virtual*/ void done();
|
||||
|
||||
/// Called when all the items are complete.
|
||||
callback_t mCallback;
|
||||
};
|
||||
|
||||
void LLInvPanelComplObserver::reset()
|
||||
{
|
||||
mIncomplete.clear();
|
||||
mComplete.clear();
|
||||
}
|
||||
|
||||
void LLInvPanelComplObserver::done()
|
||||
{
|
||||
mCallback();
|
||||
}
|
||||
|
||||
LLInventoryPanel::LLInventoryPanel(const std::string& name,
|
||||
const std::string& sort_order_setting,
|
||||
@@ -100,48 +135,66 @@ LLInventoryPanel::LLInventoryPanel(const std::string& name,
|
||||
BOOL allow_multi_select,
|
||||
LLView *parent_view) :
|
||||
LLPanel(name, rect, TRUE),
|
||||
mInventory(inventory),
|
||||
mInventoryObserver(NULL),
|
||||
mCompletionObserver(NULL),
|
||||
mFolderRoot(NULL),
|
||||
mScroller(NULL),
|
||||
mSortOrderSetting(sort_order_setting),
|
||||
mInventory(inventory),
|
||||
mAllowMultiSelect(allow_multi_select),
|
||||
mSortOrderSetting(sort_order_setting)
|
||||
mViewsInitialized(false),
|
||||
mInvFVBridgeBuilder(NULL)
|
||||
{
|
||||
mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
|
||||
|
||||
setBackgroundColor(gColors.getColor("InventoryBackgroundColor"));
|
||||
setBackgroundVisible(TRUE);
|
||||
setBackgroundOpaque(TRUE);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::buildFolderView()
|
||||
{
|
||||
LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
|
||||
LLAssetType::AT_CATEGORY,
|
||||
LLInventoryType::IT_CATEGORY,
|
||||
this,
|
||||
NULL,
|
||||
LLUUID::null);
|
||||
|
||||
mFolderRoot = createFolderView(new_listener, true/*params.use_label_suffix()*/);
|
||||
}
|
||||
BOOL LLInventoryPanel::postBuild()
|
||||
{
|
||||
init_inventory_panel_actions(this);
|
||||
|
||||
LLRect folder_rect(0,
|
||||
0,
|
||||
getRect().getWidth(),
|
||||
0);
|
||||
mFolderRoot = new LLFolderView(getName(), NULL, folder_rect, LLUUID::null, this);
|
||||
mFolderRoot->setAllowMultiSelect(mAllowMultiSelect);
|
||||
buildFolderView();
|
||||
{
|
||||
// scroller
|
||||
LLRect scroller_view_rect = getRect();
|
||||
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
|
||||
mScroller = new LLScrollableContainerView(std::string("Inventory Scroller"),
|
||||
scroller_view_rect,
|
||||
mFolderRoot);
|
||||
mScroller->setFollowsAll();
|
||||
mScroller->setReserveScrollCorner(TRUE);
|
||||
addChild(mScroller);
|
||||
mFolderRoot->setScrollContainer(mScroller);
|
||||
}
|
||||
|
||||
// scroller
|
||||
LLRect scroller_view_rect = getRect();
|
||||
scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
|
||||
mScroller = new LLScrollableContainerView(std::string("Inventory Scroller"),
|
||||
scroller_view_rect,
|
||||
mFolderRoot);
|
||||
mScroller->setFollowsAll();
|
||||
mScroller->setReserveScrollCorner(TRUE);
|
||||
addChild(mScroller);
|
||||
mFolderRoot->setScrollContainer(mScroller);
|
||||
|
||||
// set up the callbacks from the inventory we're viewing, and then
|
||||
// build everything.
|
||||
// Set up the callbacks from the inventory we're viewing, and then build everything.
|
||||
mInventoryObserver = new LLInventoryPanelObserver(this);
|
||||
mInventory->addObserver(mInventoryObserver);
|
||||
rebuildViewsFor(LLUUID::null, LLInventoryObserver::ADD);
|
||||
|
||||
// bit of a hack to make sure the inventory is open.
|
||||
mFolderRoot->openFolder(std::string("My Inventory"));
|
||||
mCompletionObserver = new LLInvPanelComplObserver(boost::bind(&LLInventoryPanel::onItemsCompletion, this));
|
||||
mInventory->addObserver(mCompletionObserver);
|
||||
|
||||
// Build view of inventory if we need default full hierarchy and inventory ready,
|
||||
// otherwise wait for idle callback.
|
||||
if (mInventory->isInventoryUsable() && !mViewsInitialized)
|
||||
{
|
||||
initializeViews();
|
||||
}
|
||||
gIdleCallbacks.addFunction(onIdle, (void*)this);
|
||||
|
||||
if (mSortOrderSetting != INHERIT_SORT_ORDER)
|
||||
{
|
||||
@@ -151,10 +204,8 @@ BOOL LLInventoryPanel::postBuild()
|
||||
{
|
||||
setSortOrder(gSavedSettings.getU32(DEFAULT_SORT_ORDER));
|
||||
}
|
||||
mFolderRoot->setSortOrder(mFolderRoot->getFilter()->getSortOrder());
|
||||
|
||||
|
||||
return TRUE;
|
||||
getFilter()->setFilterEmptySystemFolders();
|
||||
return LLPanel::postBuild();
|
||||
}
|
||||
|
||||
LLInventoryPanel::~LLInventoryPanel()
|
||||
@@ -168,9 +219,14 @@ LLInventoryPanel::~LLInventoryPanel()
|
||||
}
|
||||
}
|
||||
|
||||
gIdleCallbacks.deleteFunction(onIdle, this);
|
||||
|
||||
// LLView destructor will take care of the sub-views.
|
||||
mInventory->removeObserver(mInventoryObserver);
|
||||
mInventory->removeObserver(mCompletionObserver);
|
||||
delete mInventoryObserver;
|
||||
delete mCompletionObserver;
|
||||
|
||||
mScroller = NULL;
|
||||
}
|
||||
|
||||
@@ -186,6 +242,18 @@ LLXMLNodePtr LLInventoryPanel::getXML(bool save_children) const
|
||||
return node;
|
||||
}
|
||||
|
||||
class LLInventoryRecentItemsPanel : public LLInventoryPanel
|
||||
{
|
||||
public:
|
||||
LLInventoryRecentItemsPanel(const std::string& name,
|
||||
const std::string& sort_order_setting,
|
||||
const LLRect& rect,
|
||||
LLInventoryModel* inventory,
|
||||
BOOL allow_multi_select,
|
||||
LLView *parent_view);
|
||||
|
||||
};
|
||||
|
||||
LLView* LLInventoryPanel::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
|
||||
{
|
||||
LLInventoryPanel* panel;
|
||||
@@ -202,7 +270,12 @@ LLView* LLInventoryPanel::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
|
||||
std::string sort_order(INHERIT_SORT_ORDER);
|
||||
node->getAttributeString("sort_order", sort_order);
|
||||
|
||||
panel = new LLInventoryPanel(name, sort_order,
|
||||
if(name != "Recent Items")
|
||||
panel = new LLInventoryPanel(name, sort_order,
|
||||
rect, &gInventory,
|
||||
allow_multi_select, parent);
|
||||
else
|
||||
panel = new LLInventoryRecentItemsPanel(name, sort_order,
|
||||
rect, &gInventory,
|
||||
allow_multi_select, parent);
|
||||
|
||||
@@ -215,11 +288,8 @@ LLView* LLInventoryPanel::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
|
||||
|
||||
void LLInventoryPanel::draw()
|
||||
{
|
||||
// select the desired item (in case it wasn't loaded when the selection was requested)
|
||||
if (mSelectThisID.notNull())
|
||||
{
|
||||
setSelection(mSelectThisID, false);
|
||||
}
|
||||
// Select the desired item (in case it wasn't loaded when the selection was requested)
|
||||
mFolderRoot->updateSelection();
|
||||
LLPanel::draw();
|
||||
}
|
||||
|
||||
@@ -241,14 +311,17 @@ const LLInventoryFilter* LLInventoryPanel::getFilter() const
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void LLInventoryPanel::setFilterTypes(U32 filter_types)
|
||||
void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
|
||||
{
|
||||
getFilter()->setFilterTypes(filter_types);
|
||||
}
|
||||
if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT)
|
||||
getFilter()->setFilterObjectTypes(types);
|
||||
if (filter_type == LLInventoryFilter::FILTERTYPE_CATEGORY)
|
||||
getFilter()->setFilterCategoryTypes(types);
|
||||
}
|
||||
|
||||
U32 LLInventoryPanel::getFilterTypes() const
|
||||
U32 LLInventoryPanel::getFilterObjectTypes() const
|
||||
{
|
||||
return mFolderRoot->getFilterTypes();
|
||||
return mFolderRoot->getFilterObjectTypes();
|
||||
}
|
||||
|
||||
U32 LLInventoryPanel::getFilterPermMask() const
|
||||
@@ -256,11 +329,17 @@ U32 LLInventoryPanel::getFilterPermMask() const
|
||||
return mFolderRoot->getFilterPermissions();
|
||||
}
|
||||
|
||||
|
||||
void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)
|
||||
{
|
||||
getFilter()->setFilterPermissions(filter_perm_mask);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::setFilterWearableTypes(U64 types)
|
||||
{
|
||||
getFilter()->setFilterWearableTypes(types);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::setFilterWorn(bool worn)
|
||||
{
|
||||
getFilter()->setFilterWorn(worn);
|
||||
@@ -276,6 +355,7 @@ const std::string LLInventoryPanel::getFilterSubString()
|
||||
return mFolderRoot->getFilterSubString();
|
||||
}
|
||||
|
||||
|
||||
void LLInventoryPanel::setSortOrder(U32 order)
|
||||
{
|
||||
getFilter()->setSortOrder(order);
|
||||
@@ -292,6 +372,11 @@ U32 LLInventoryPanel::getSortOrder() const
|
||||
return mFolderRoot->getSortOrder();
|
||||
}
|
||||
|
||||
void LLInventoryPanel::requestSort()
|
||||
{
|
||||
mFolderRoot->requestSort();
|
||||
}
|
||||
|
||||
void LLInventoryPanel::setSinceLogoff(BOOL sl)
|
||||
{
|
||||
getFilter()->setDateRangeLastLogoff(sl);
|
||||
@@ -302,6 +387,11 @@ void LLInventoryPanel::setHoursAgo(U32 hours)
|
||||
getFilter()->setHoursAgo(hours);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::setFilterLinks(U64 filter_links)
|
||||
{
|
||||
getFilter()->setFilterLinks(filter_links);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show)
|
||||
{
|
||||
getFilter()->setShowFolderState(show);
|
||||
@@ -319,8 +409,8 @@ void LLInventoryPanel::modelChanged(U32 mask)
|
||||
|
||||
bool handled = false;
|
||||
|
||||
//if (!mViewsInitialized) return;
|
||||
|
||||
if (!mViewsInitialized) return;
|
||||
|
||||
const LLInventoryModel* model = getModel();
|
||||
if (!model) return;
|
||||
|
||||
@@ -337,7 +427,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
|
||||
|
||||
// LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item
|
||||
// to folder is the fast way to get a folder without searching through folders tree.
|
||||
//LLFolderViewFolder* view_folder = dynamic_cast<LLFolderViewFolder*>(view_item);
|
||||
LLFolderViewFolder* view_folder = dynamic_cast<LLFolderViewFolder*>(view_item);
|
||||
|
||||
//////////////////////////////
|
||||
// LABEL Operation
|
||||
@@ -361,7 +451,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
|
||||
//////////////////////////////
|
||||
// REBUILD Operation
|
||||
// Destroy and regenerate the UI.
|
||||
/*if (mask & LLInventoryObserver::REBUILD)
|
||||
if (mask & LLInventoryObserver::REBUILD)
|
||||
{
|
||||
handled = true;
|
||||
if (model_item && view_item)
|
||||
@@ -370,7 +460,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
|
||||
}
|
||||
view_item = buildNewViews(item_id);
|
||||
view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
|
||||
}*/
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// INTERNAL Operation
|
||||
@@ -386,13 +476,13 @@ void LLInventoryPanel::modelChanged(U32 mask)
|
||||
//////////////////////////////
|
||||
// SORT Operation
|
||||
// Sort the folder.
|
||||
/*if (mask & LLInventoryObserver::SORT)
|
||||
if (mask & LLInventoryObserver::SORT)
|
||||
{
|
||||
if (view_folder)
|
||||
{
|
||||
view_folder->requestSort();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
// We don't typically care which of these masks the item is actually flagged with, since the masks
|
||||
// may not be accurate (e.g. in the main inventory panel, I move an item from My Inventory into
|
||||
@@ -463,20 +553,86 @@ LLFolderView* LLInventoryPanel::getRootFolder()
|
||||
{
|
||||
return mFolderRoot;
|
||||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLInventoryPanel::onIdle(void *userdata)
|
||||
{
|
||||
if (!gInventory.isInventoryUsable())
|
||||
return;
|
||||
|
||||
LLInventoryPanel *self = (LLInventoryPanel*)userdata;
|
||||
// Inventory just initialized, do complete build
|
||||
if (!self->mViewsInitialized)
|
||||
{
|
||||
self->initializeViews();
|
||||
}
|
||||
if (self->mViewsInitialized)
|
||||
{
|
||||
gIdleCallbacks.deleteFunction(onIdle, (void*)self);
|
||||
}
|
||||
}
|
||||
|
||||
const LLUUID& LLInventoryPanel::getRootFolderID() const
|
||||
{
|
||||
return mFolderRoot->getListener()->getUUID();
|
||||
}
|
||||
void LLInventoryPanel::rebuildViewsFor(const LLUUID& id, U32 mask)
|
||||
|
||||
void LLInventoryPanel::initializeViews()
|
||||
{
|
||||
if (!gInventory.isInventoryUsable()) return;
|
||||
|
||||
rebuildViewsFor(getRootFolderID());
|
||||
|
||||
mViewsInitialized = true;
|
||||
|
||||
openStartFolderOrMyInventory();
|
||||
|
||||
// Special case for new user login
|
||||
if (gAgent.isFirstLogin())
|
||||
{
|
||||
// Auto open the user's library
|
||||
LLFolderViewFolder* lib_folder = mFolderRoot->getFolderByID(gInventory.getLibraryRootFolderID());
|
||||
if (lib_folder)
|
||||
{
|
||||
lib_folder->setOpen(TRUE);
|
||||
}
|
||||
|
||||
// Auto close the user's my inventory folder
|
||||
LLFolderViewFolder* my_inv_folder = mFolderRoot->getFolderByID(gInventory.getRootFolderID());
|
||||
if (my_inv_folder)
|
||||
{
|
||||
my_inv_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
|
||||
}
|
||||
}
|
||||
}
|
||||
LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
|
||||
{
|
||||
// Destroy the old view for this ID so we can rebuild it.
|
||||
LLFolderViewItem* old_view = mFolderRoot->getItemByID(id);
|
||||
if (old_view && id.notNull())
|
||||
if (old_view)
|
||||
{
|
||||
old_view->destroyView();
|
||||
}
|
||||
|
||||
buildNewViews(id);
|
||||
return buildNewViews(id);
|
||||
}
|
||||
|
||||
LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix)
|
||||
{
|
||||
LLRect folder_rect(0,
|
||||
0,
|
||||
getRect().getWidth(),
|
||||
0);
|
||||
|
||||
LLFolderView* ret = new LLFolderView(
|
||||
getName(),
|
||||
folder_rect,
|
||||
LLUUID::null,
|
||||
this,
|
||||
bridge);
|
||||
ret->setAllowMultiSelect(mAllowMultiSelect);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
|
||||
@@ -484,6 +640,8 @@ LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * br
|
||||
return new LLFolderViewFolder(
|
||||
bridge->getDisplayName(),
|
||||
bridge->getIcon(),
|
||||
bridge->getOpenIcon(),
|
||||
LLUI::getUIImage("inv_link_overlay.tga"),
|
||||
mFolderRoot,
|
||||
bridge);
|
||||
}
|
||||
@@ -493,76 +651,81 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
|
||||
return new LLFolderViewItem(
|
||||
bridge->getDisplayName(),
|
||||
bridge->getIcon(),
|
||||
bridge->getOpenIcon(),
|
||||
LLUI::getUIImage("inv_link_overlay.tga"),
|
||||
bridge->getCreationDate(),
|
||||
mFolderRoot,
|
||||
bridge);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::buildNewViews(const LLUUID& id)
|
||||
LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
|
||||
{
|
||||
LLInventoryObject* const objectp = gInventory.getObject(id);
|
||||
LLInventoryObject const* objectp = gInventory.getObject(id);
|
||||
LLUUID root_id = mFolderRoot->getListener()->getUUID();
|
||||
LLFolderViewFolder* parent_folder = NULL;
|
||||
LLFolderViewItem* itemp = NULL;
|
||||
|
||||
|
||||
if (objectp)
|
||||
{
|
||||
const LLUUID &parent_id = objectp->getParentUUID();
|
||||
LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
|
||||
if (objectp->getType() <= LLAssetType::AT_NONE ||
|
||||
objectp->getType() >= LLAssetType::AT_COUNT)
|
||||
{
|
||||
if (id == root_id)
|
||||
{
|
||||
parent_folder = mFolderRoot;
|
||||
}
|
||||
else if (objectp)
|
||||
{
|
||||
const LLUUID &parent_id = objectp->getParentUUID();
|
||||
parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
|
||||
|
||||
if (parent_folder)
|
||||
{
|
||||
if (objectp->getType() <= LLAssetType::AT_NONE ||
|
||||
objectp->getType() >= LLAssetType::AT_COUNT)
|
||||
{
|
||||
llwarns << "LLInventoryPanel::buildNewViews called with invalid objectp->mType : "
|
||||
<< ((S32) objectp->getType()) << " name " << objectp->getName() << " UUID " << objectp->getUUID()
|
||||
<< llendl;
|
||||
}
|
||||
else if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
|
||||
(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER)) // build new view for category
|
||||
{
|
||||
LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(objectp->getType(),
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((objectp->getType() == LLAssetType::AT_CATEGORY) &&
|
||||
(objectp->getActualType() != LLAssetType::AT_LINK_FOLDER))
|
||||
{
|
||||
LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(objectp->getType(),
|
||||
objectp->getType(),
|
||||
LLInventoryType::IT_CATEGORY,
|
||||
this,
|
||||
mFolderRoot,
|
||||
objectp->getUUID());
|
||||
|
||||
if (new_listener)
|
||||
if (new_listener)
|
||||
{
|
||||
LLFolderViewFolder* folderp = createFolderViewFolder(new_listener);
|
||||
if (folderp)
|
||||
{
|
||||
folderp->setItemSortOrder(mFolderRoot->getSortOrder());
|
||||
}
|
||||
itemp = folderp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LLFolderViewFolder* folderp = createFolderViewFolder(new_listener);
|
||||
if (folderp)
|
||||
{
|
||||
folderp->setItemSortOrder(mFolderRoot->getSortOrder());
|
||||
}
|
||||
itemp = folderp;
|
||||
}
|
||||
}
|
||||
else // build new view for item
|
||||
{
|
||||
LLInventoryItem* item = (LLInventoryItem*)objectp;
|
||||
LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(
|
||||
item->getType(),
|
||||
// Build new view for item.
|
||||
LLInventoryItem* item = (LLInventoryItem*)objectp;
|
||||
LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(item->getType(),
|
||||
item->getActualType(),
|
||||
item->getInventoryType(),
|
||||
this,
|
||||
item->getUUID(),
|
||||
item->getFlags());
|
||||
this,
|
||||
mFolderRoot,
|
||||
item->getUUID(),
|
||||
item->getFlags());
|
||||
|
||||
if (new_listener)
|
||||
{
|
||||
itemp = createFolderViewItem(new_listener);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (itemp)
|
||||
{
|
||||
if (parent_folder)
|
||||
{
|
||||
itemp->addToFolder(parent_folder, mFolderRoot);
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "Couldn't find parent folder for child " << itemp->getLabel() << llendl;
|
||||
delete itemp;
|
||||
}
|
||||
}
|
||||
|
||||
if (itemp)
|
||||
{
|
||||
itemp->addToFolder(parent_folder, mFolderRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,7 +750,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
|
||||
}
|
||||
}
|
||||
|
||||
if(items)
|
||||
if(items && parent_folder)
|
||||
{
|
||||
for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
|
||||
item_iter != items->end();
|
||||
@@ -599,6 +762,25 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
|
||||
}
|
||||
mInventory->unlockDirectDescendentArrays(id);
|
||||
}
|
||||
|
||||
return itemp;
|
||||
}
|
||||
|
||||
// bit of a hack to make sure the inventory is open.
|
||||
void LLInventoryPanel::openStartFolderOrMyInventory()
|
||||
{
|
||||
// Find My Inventory folder and open it up by name
|
||||
for (LLView *child = mFolderRoot->getFirstChild(); child; child = mFolderRoot->findNextSibling(child))
|
||||
{
|
||||
LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
|
||||
if (fchild
|
||||
&& fchild->getListener()
|
||||
&& fchild->getListener()->getUUID() == gInventory.getRootFolderID())
|
||||
{
|
||||
fchild->setOpen(TRUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct LLConfirmPurgeData
|
||||
@@ -633,6 +815,10 @@ protected:
|
||||
const LLUUID& mID;
|
||||
};
|
||||
|
||||
void LLInventoryPanel::onItemsCompletion()
|
||||
{
|
||||
if (mFolderRoot) mFolderRoot->updateMenu();
|
||||
}
|
||||
|
||||
void LLInventoryPanel::openSelected()
|
||||
{
|
||||
@@ -674,17 +860,47 @@ BOOL LLInventoryPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg)
|
||||
{
|
||||
BOOL handled = FALSE;
|
||||
|
||||
BOOL handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
|
||||
|
||||
if (handled)
|
||||
//if (mAcceptsDragAndDrop)
|
||||
{
|
||||
mFolderRoot->setDragAndDropThisFrame();
|
||||
handled = LLPanel::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
|
||||
|
||||
// If folder view is empty the (x, y) point won't be in its rect
|
||||
// so the handler must be called explicitly.
|
||||
// but only if was not handled before. See EXT-6746.
|
||||
if (!handled && !mFolderRoot->hasVisibleChildren())
|
||||
{
|
||||
handled = mFolderRoot->handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
|
||||
}
|
||||
|
||||
if (handled)
|
||||
{
|
||||
mFolderRoot->setDragAndDropThisFrame();
|
||||
}
|
||||
}
|
||||
|
||||
return handled;
|
||||
}
|
||||
|
||||
void LLInventoryPanel::onFocusLost()
|
||||
{
|
||||
// inventory no longer handles cut/copy/paste/delete
|
||||
if (LLEditMenuHandler::gEditMenuHandler == mFolderRoot)
|
||||
{
|
||||
LLEditMenuHandler::gEditMenuHandler = NULL;
|
||||
}
|
||||
|
||||
LLPanel::onFocusLost();
|
||||
}
|
||||
|
||||
void LLInventoryPanel::onFocusReceived()
|
||||
{
|
||||
// inventory now handles cut/copy/paste/delete
|
||||
LLEditMenuHandler::gEditMenuHandler = mFolderRoot;
|
||||
|
||||
LLPanel::onFocusReceived();
|
||||
}
|
||||
|
||||
void LLInventoryPanel::openAllFolders()
|
||||
{
|
||||
@@ -707,30 +923,52 @@ void LLInventoryPanel::openDefaultFolderForType(LLAssetType::EType type)
|
||||
|
||||
void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus)
|
||||
{
|
||||
LLFolderViewItem* itemp = mFolderRoot->getItemByID(obj_id);
|
||||
if(itemp && itemp->getListener())
|
||||
// Don't select objects in COF (e.g. to prevent refocus when items are worn).
|
||||
const LLInventoryObject *obj = gInventory.getObject(obj_id);
|
||||
if (obj && obj->getParentUUID() == LLAppearanceMgr::instance().getCOF())
|
||||
{
|
||||
itemp->getListener()->arrangeAndSet(itemp, TRUE, take_keyboard_focus);
|
||||
mSelectThisID.setNull();
|
||||
return;
|
||||
}
|
||||
else
|
||||
mFolderRoot->setSelectionByID(obj_id, take_keyboard_focus);
|
||||
}
|
||||
|
||||
void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb)
|
||||
{
|
||||
if (mFolderRoot)
|
||||
{
|
||||
// save the desired item to be selected later (if/when ready)
|
||||
mSelectThisID = obj_id;
|
||||
}
|
||||
}
|
||||
void LLInventoryPanel::setSelectCallback(LLFolderView::SelectCallback callback, void* user_data)
|
||||
{
|
||||
if (mFolderRoot)
|
||||
{
|
||||
mFolderRoot->setSelectCallback(callback, user_data);
|
||||
mFolderRoot->setSelectCallback(cb);
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryPanel::clearSelection()
|
||||
{
|
||||
mFolderRoot->clearSelection();
|
||||
mSelectThisID.setNull();
|
||||
}
|
||||
|
||||
void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)
|
||||
{
|
||||
// Schedule updating the folder view context menu when all selected items become complete (STORM-373).
|
||||
mCompletionObserver->reset();
|
||||
for (std::deque<LLFolderViewItem*>::const_iterator it = items.begin(); it != items.end(); ++it)
|
||||
{
|
||||
LLUUID id = (*it)->getListener()->getUUID();
|
||||
LLViewerInventoryItem* inv_item = mInventory->getItem(id);
|
||||
|
||||
if (inv_item && !inv_item->isFinished())
|
||||
{
|
||||
mCompletionObserver->watchItem(id);
|
||||
}
|
||||
}
|
||||
|
||||
LLFolderView* fv = getRootFolder();
|
||||
if (fv->needsAutoRename()) // auto-selecting a new user-created asset and preparing to rename
|
||||
{
|
||||
fv->setNeedsAutoRename(FALSE);
|
||||
if (items.size()) // new asset is visible and selected
|
||||
{
|
||||
fv->startRenamingSelectedItem();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLInventoryPanel::createNewItem(const std::string& name,
|
||||
@@ -773,3 +1011,60 @@ void LLInventoryPanel::dumpSelectionInformation(void* user_data)
|
||||
LLInventoryPanel* iv = (LLInventoryPanel*)user_data;
|
||||
iv->mFolderRoot->dumpSelectionInformation();
|
||||
}
|
||||
// static
|
||||
LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
|
||||
{
|
||||
LLInventoryPanel* res = NULL;
|
||||
LLInventoryView* floater_inventory = LLInventoryView::getActiveInventory();
|
||||
if (!floater_inventory)
|
||||
{
|
||||
llwarns << "Could not find My Inventory floater" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
res = floater_inventory ? floater_inventory->getActivePanel() : NULL;
|
||||
if (res)
|
||||
{
|
||||
// Make sure the floater is not minimized (STORM-438).
|
||||
if (floater_inventory && floater_inventory->isMinimized())
|
||||
{
|
||||
floater_inventory->setMinimized(FALSE);
|
||||
}
|
||||
}
|
||||
else if (auto_open)
|
||||
{
|
||||
floater_inventory->open();
|
||||
|
||||
res = floater_inventory->getActivePanel();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
void LLInventoryPanel::addHideFolderType(LLFolderType::EType folder_type)
|
||||
{
|
||||
getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << folder_type));
|
||||
}
|
||||
|
||||
BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) const
|
||||
{
|
||||
return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));
|
||||
}
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* Recent Inventory Panel related class */
|
||||
/************************************************************************/
|
||||
class LLInventoryRecentItemsPanel;
|
||||
static const LLRecentInventoryBridgeBuilder RECENT_ITEMS_BUILDER;
|
||||
|
||||
|
||||
LLInventoryRecentItemsPanel:: LLInventoryRecentItemsPanel(const std::string& name,
|
||||
const std::string& sort_order_setting,
|
||||
const LLRect& rect,
|
||||
LLInventoryModel* inventory,
|
||||
BOOL allow_multi_select,
|
||||
LLView *parent_view) :
|
||||
LLInventoryPanel(name, sort_order_setting,rect,inventory,allow_multi_select,parent_view)
|
||||
{
|
||||
mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -47,16 +47,13 @@
|
||||
#include "lluictrlfactory.h"
|
||||
#include <set>
|
||||
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// Class LLInventoryView
|
||||
//
|
||||
// This is the controller class specific for handling agent
|
||||
// inventory. It deals with the buttons and views used to navigate as
|
||||
// well as controls the behavior of the overall object.
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
class LLFolderView;
|
||||
class LLFolderViewFolder;
|
||||
class LLFolderViewItem;
|
||||
class LLInventoryFilter;
|
||||
class LLInventoryModel;
|
||||
class LLInvFVBridge;
|
||||
class LLInventoryFVBridgeBuilder;
|
||||
class LLMenuBarGL;
|
||||
class LLCheckBoxCtrl;
|
||||
class LLSpinCtrl;
|
||||
@@ -65,19 +62,21 @@ class LLTextBox;
|
||||
class LLIconCtrl;
|
||||
class LLSaveFolderState;
|
||||
class LLSearchEditor;
|
||||
|
||||
class LLInvPanelComplObserver;
|
||||
|
||||
class LLInventoryPanel : public LLPanel
|
||||
{
|
||||
public:
|
||||
protected:
|
||||
LLInventoryPanel(const std::string& name,
|
||||
const std::string& sort_order_setting,
|
||||
const LLRect& rect,
|
||||
LLInventoryModel* inventory,
|
||||
BOOL allow_multi_select,
|
||||
LLView *parent_view = NULL);
|
||||
~LLInventoryPanel();
|
||||
public:
|
||||
virtual ~LLInventoryPanel();
|
||||
|
||||
public:
|
||||
LLInventoryModel* getModel() { return mInventory; }
|
||||
|
||||
BOOL postBuild();
|
||||
@@ -93,20 +92,24 @@ public:
|
||||
void* cargo_data,
|
||||
EAcceptance* accept,
|
||||
std::string& tooltip_msg);
|
||||
// LLUICtrl methods
|
||||
/*virtual*/ void onFocusLost();
|
||||
/*virtual*/ void onFocusReceived();
|
||||
|
||||
// Call this method to set the selection.
|
||||
void openAllFolders();
|
||||
void closeAllFolders();
|
||||
void openDefaultFolderForType(LLAssetType::EType);
|
||||
void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
|
||||
void setSelectCallback(LLFolderView::SelectCallback callback, void* user_data);
|
||||
void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
|
||||
void clearSelection();
|
||||
LLInventoryFilter* getFilter();
|
||||
const LLInventoryFilter* getFilter() const;
|
||||
void setFilterTypes(U32 filter);
|
||||
U32 getFilterTypes() const;
|
||||
void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
|
||||
U32 getFilterObjectTypes() const;
|
||||
void setFilterPermMask(PermissionMask filter_perm_mask);
|
||||
U32 getFilterPermMask() const;
|
||||
void setFilterWearableTypes(U64 filter);
|
||||
void setFilterSubString(const std::string& string);
|
||||
const std::string getFilterSubString();
|
||||
void setFilterWorn(bool worn);
|
||||
@@ -115,7 +118,8 @@ public:
|
||||
void setSinceLogoff(BOOL sl);
|
||||
void setHoursAgo(U32 hours);
|
||||
BOOL getSinceLogoff();
|
||||
|
||||
void setFilterLinks(U64 filter_links);
|
||||
|
||||
void setShowFolderState(LLInventoryFilter::EFolderShow show);
|
||||
LLInventoryFilter::EFolderShow getShowFolderState();
|
||||
void setAllowMultiSelect(BOOL allow) { mFolderRoot->setAllowMultiSelect(allow); }
|
||||
@@ -123,17 +127,19 @@ public:
|
||||
void modelChanged(U32 mask);
|
||||
LLFolderView* getRootFolder();
|
||||
LLScrollableContainerView* getScrollableContainer() { return mScroller; }
|
||||
|
||||
|
||||
void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
|
||||
// DEBUG ONLY:
|
||||
static void dumpSelectionInformation(void* user_data);
|
||||
|
||||
void openSelected();
|
||||
void unSelectAll();
|
||||
|
||||
static void onIdle(void* user_data);
|
||||
|
||||
protected:
|
||||
// Given the id and the parent, build all of the folder views.
|
||||
void rebuildViewsFor(const LLUUID& id, U32 mask);
|
||||
void buildNewViews(const LLUUID& id);
|
||||
// Find whichever inventory panel is active / on top.
|
||||
// "Auto_open" determines if we open an inventory panel if none are open.
|
||||
static LLInventoryPanel *getActiveInventoryPanel(BOOL auto_open = TRUE);
|
||||
|
||||
public:
|
||||
// TomY TODO: Move this elsewhere?
|
||||
@@ -147,13 +153,27 @@ public:
|
||||
U32 next_owner_perm = 0);
|
||||
|
||||
protected:
|
||||
void openStartFolderOrMyInventory(); // open the first level of inventory
|
||||
void onItemsCompletion(); // called when selected items are complete
|
||||
|
||||
LLInventoryModel* mInventory;
|
||||
LLInventoryObserver* mInventoryObserver;
|
||||
|
||||
LLInvPanelComplObserver* mCompletionObserver;
|
||||
|
||||
BOOL mAllowMultiSelect;
|
||||
LLFolderView* mFolderRoot;
|
||||
LLScrollableContainerView* mScroller;
|
||||
|
||||
/**
|
||||
* Pointer to LLInventoryFVBridgeBuilder.
|
||||
*
|
||||
* It is set in LLInventoryPanel's constructor and can be overridden in derived classes with
|
||||
* another implementation.
|
||||
* Take into account it will not be deleted by LLInventoryPanel itself.
|
||||
*/
|
||||
const LLInventoryFVBridgeBuilder* mInvFVBridgeBuilder;
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Sorting
|
||||
//--------------------------------------------------------------------
|
||||
@@ -162,18 +182,36 @@ public:
|
||||
static const std::string RECENTITEMS_SORT_ORDER;
|
||||
static const std::string WORNITEMS_SORT_ORDER;
|
||||
static const std::string INHERIT_SORT_ORDER;
|
||||
|
||||
|
||||
void setSortOrder(U32 order);
|
||||
U32 getSortOrder() const;
|
||||
void requestSort();
|
||||
|
||||
private:
|
||||
const std::string mSortOrderSetting;
|
||||
LLUUID mSelectThisID; // if non null, select this item
|
||||
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// Hidden folders
|
||||
//--------------------------------------------------------------------
|
||||
public:
|
||||
void addHideFolderType(LLFolderType::EType folder_type);
|
||||
|
||||
public:
|
||||
BOOL getIsViewsInitialized() const { return mViewsInitialized; }
|
||||
const LLUUID& getRootFolderID() const;
|
||||
protected:
|
||||
// Builds the UI. Call this once the inventory is usable.
|
||||
void initializeViews();
|
||||
LLFolderViewItem* rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views.
|
||||
|
||||
virtual void buildFolderView();
|
||||
LLFolderViewItem* buildNewViews(const LLUUID& id);
|
||||
BOOL getIsHiddenFolderType(LLFolderType::EType folder_type) const;
|
||||
|
||||
virtual LLFolderView* createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix);
|
||||
virtual LLFolderViewFolder* createFolderViewFolder(LLInvFVBridge * bridge);
|
||||
virtual LLFolderViewItem* createFolderViewItem(LLInvFVBridge * bridge);
|
||||
BOOL mViewsInitialized; // Views have been generated
|
||||
};
|
||||
|
||||
class LLInventoryView;
|
||||
@@ -193,11 +231,6 @@ void init_inventory_panel_actions(LLInventoryPanel *panel);
|
||||
|
||||
class LLInventoryCategory;
|
||||
class LLInventoryItem;
|
||||
//void wear_inventory_category_on_avatar(LLInventoryCategory* category);
|
||||
|
||||
void wear_inventory_item_on_avatar(LLInventoryItem* item);
|
||||
void wear_outfit_by_name(const std::string& name);
|
||||
void wear_inventory_category(LLInventoryCategory* category, bool copy, bool append);
|
||||
|
||||
// These methods can open items without the inventory being visible
|
||||
void open_notecard(LLViewerInventoryItem* inv_item, const std::string& title, const LLUUID& object_id, BOOL show_keep_discard, const LLUUID& source_id = LLUUID::null, BOOL take_focus = TRUE);
|
||||
|
||||
@@ -78,8 +78,7 @@ LLJoystick::LLJoystick(
|
||||
mHeldDown(FALSE),
|
||||
mHeldDownTimer()
|
||||
{
|
||||
setHeldDownCallback(&LLJoystick::onHeldDown);
|
||||
setCallbackUserData(this);
|
||||
setHeldDownCallback(boost::bind(&LLJoystick::onHeldDownCallback,this));
|
||||
}
|
||||
|
||||
|
||||
@@ -178,7 +177,7 @@ F32 LLJoystick::getElapsedHeldDownTime()
|
||||
}
|
||||
|
||||
// static
|
||||
void LLJoystick::onHeldDown(void *userdata)
|
||||
void LLJoystick::onHeldDownCallback(void *userdata)
|
||||
{
|
||||
LLJoystick *self = (LLJoystick *)userdata;
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
virtual void onHeldDown() = 0;
|
||||
F32 getElapsedHeldDownTime();
|
||||
|
||||
static void onHeldDown(void *userdata); // called by llbutton callback handler
|
||||
static void onHeldDownCallback(void *userdata); // called by llbutton callback handler
|
||||
void setInitialQuadrant(EJoystickQuadrant initial) { mInitialQuadrant = initial; };
|
||||
|
||||
virtual LLXMLNodePtr getXML(bool save_children = true) const;
|
||||
|
||||
@@ -105,7 +105,7 @@ void LLLocalInventory::open(LLUUID item_id)
|
||||
rect,
|
||||
"",
|
||||
item_id,
|
||||
0);
|
||||
LLPreviewAnim::NONE);
|
||||
floaterp->setFocus(TRUE);
|
||||
gFloaterView->adjustToFitScreen(floaterp, FALSE);
|
||||
}
|
||||
@@ -333,8 +333,7 @@ void LLLocalInventory::loadInvCache(std::string filename)
|
||||
void LLLocalInventory::saveInvCache(std::string filename, LLFolderView* folder)
|
||||
{
|
||||
LLInventoryModel* model = &gInventory;
|
||||
std::set<LLUUID> selected_items;
|
||||
folder->getSelectionList(selected_items);
|
||||
std::set<LLUUID> selected_items = folder->getSelectionList();
|
||||
if(selected_items.size() < 1)
|
||||
{
|
||||
// No items selected? Wtfboom
|
||||
|
||||
212
indra/newview/lllocaltextureobject.cpp
Normal file
212
indra/newview/lllocaltextureobject.cpp
Normal file
@@ -0,0 +1,212 @@
|
||||
/**
|
||||
* @file lllocaltextureobject.cpp
|
||||
*
|
||||
* $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 "lllocaltextureobject.h"
|
||||
|
||||
#include "lltexlayer.h"
|
||||
#include "llviewertexture.h"
|
||||
#include "lltextureentry.h"
|
||||
#include "lluuid.h"
|
||||
#include "llwearable.h"
|
||||
|
||||
|
||||
LLLocalTextureObject::LLLocalTextureObject() :
|
||||
mIsBakedReady(FALSE),
|
||||
mDiscard(MAX_DISCARD_LEVEL+1)
|
||||
{
|
||||
mImage = NULL;
|
||||
}
|
||||
|
||||
LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id) :
|
||||
mIsBakedReady(FALSE),
|
||||
mDiscard(MAX_DISCARD_LEVEL+1)
|
||||
{
|
||||
mImage = image;
|
||||
gGL.getTexUnit(0)->bind(mImage);
|
||||
mID = id;
|
||||
}
|
||||
|
||||
LLLocalTextureObject::LLLocalTextureObject(const LLLocalTextureObject& lto) :
|
||||
mImage(lto.mImage),
|
||||
mID(lto.mID),
|
||||
mIsBakedReady(lto.mIsBakedReady),
|
||||
mDiscard(lto.mDiscard)
|
||||
{
|
||||
U32 num_layers = lto.getNumTexLayers();
|
||||
mTexLayers.reserve(num_layers);
|
||||
for (U32 index = 0; index < num_layers; index++)
|
||||
{
|
||||
LLTexLayer* original_layer = lto.getTexLayer(index);
|
||||
if (!original_layer)
|
||||
{
|
||||
llerrs << "could not clone Local Texture Object: unable to extract texlayer!" << llendl;
|
||||
continue;
|
||||
}
|
||||
|
||||
LLTexLayer* new_layer = new LLTexLayer(*original_layer);
|
||||
new_layer->setLTO(this);
|
||||
mTexLayers.push_back(new_layer);
|
||||
}
|
||||
}
|
||||
|
||||
LLLocalTextureObject::~LLLocalTextureObject()
|
||||
{
|
||||
}
|
||||
|
||||
LLViewerFetchedTexture* LLLocalTextureObject::getImage() const
|
||||
{
|
||||
return mImage;
|
||||
}
|
||||
|
||||
LLTexLayer* LLLocalTextureObject::getTexLayer(U32 index) const
|
||||
{
|
||||
if (index >= getNumTexLayers())
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mTexLayers[index];
|
||||
}
|
||||
|
||||
LLTexLayer* LLLocalTextureObject::getTexLayer(const std::string &name)
|
||||
{
|
||||
for( tex_layer_vec_t::iterator iter = mTexLayers.begin(); iter != mTexLayers.end(); iter++)
|
||||
{
|
||||
LLTexLayer *layer = *iter;
|
||||
if (layer->getName().compare(name) == 0)
|
||||
{
|
||||
return layer;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U32 LLLocalTextureObject::getNumTexLayers() const
|
||||
{
|
||||
return mTexLayers.size();
|
||||
}
|
||||
|
||||
LLUUID LLLocalTextureObject::getID() const
|
||||
{
|
||||
return mID;
|
||||
}
|
||||
|
||||
S32 LLLocalTextureObject::getDiscard() const
|
||||
{
|
||||
return mDiscard;
|
||||
}
|
||||
|
||||
BOOL LLLocalTextureObject::getBakedReady() const
|
||||
{
|
||||
return mIsBakedReady;
|
||||
}
|
||||
|
||||
void LLLocalTextureObject::setImage(LLViewerFetchedTexture* new_image)
|
||||
{
|
||||
mImage = new_image;
|
||||
}
|
||||
|
||||
BOOL LLLocalTextureObject::setTexLayer(LLTexLayer *new_tex_layer, U32 index)
|
||||
{
|
||||
if (index >= getNumTexLayers() )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (new_tex_layer == NULL)
|
||||
{
|
||||
return removeTexLayer(index);
|
||||
}
|
||||
|
||||
LLTexLayer *layer = new LLTexLayer(*new_tex_layer);
|
||||
layer->setLTO(this);
|
||||
|
||||
if (mTexLayers[index])
|
||||
{
|
||||
delete mTexLayers[index];
|
||||
}
|
||||
mTexLayers[index] = layer;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLLocalTextureObject::addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable)
|
||||
{
|
||||
if (new_tex_layer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LLTexLayer *layer = new LLTexLayer(*new_tex_layer, wearable);
|
||||
layer->setLTO(this);
|
||||
mTexLayers.push_back(layer);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLLocalTextureObject::addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable)
|
||||
{
|
||||
if (new_tex_layer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LLTexLayer *layer = new LLTexLayer(*new_tex_layer, this, wearable);
|
||||
layer->setLTO(this);
|
||||
mTexLayers.push_back(layer);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLLocalTextureObject::removeTexLayer(U32 index)
|
||||
{
|
||||
if (index >= getNumTexLayers())
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
tex_layer_vec_t::iterator iter = mTexLayers.begin();
|
||||
iter += index;
|
||||
|
||||
delete *iter;
|
||||
mTexLayers.erase(iter);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLLocalTextureObject::setID(LLUUID new_id)
|
||||
{
|
||||
mID = new_id;
|
||||
}
|
||||
|
||||
void LLLocalTextureObject::setDiscard(S32 new_discard)
|
||||
{
|
||||
mDiscard = new_discard;
|
||||
}
|
||||
|
||||
void LLLocalTextureObject::setBakedReady(BOOL ready)
|
||||
{
|
||||
mIsBakedReady = ready;
|
||||
}
|
||||
|
||||
87
indra/newview/lllocaltextureobject.h
Normal file
87
indra/newview/lllocaltextureobject.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* @file lllocaltextureobject.h
|
||||
* @brief LLLocalTextureObject class header file
|
||||
*
|
||||
* $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_LOCALTEXTUREOBJECT_H
|
||||
#define LL_LOCALTEXTUREOBJECT_H
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "llviewertexture.h"
|
||||
|
||||
class LLUUID;
|
||||
class LLTexLayer;
|
||||
class LLTextureEntry;
|
||||
class LLTexLayerTemplate;
|
||||
class LLWearable;
|
||||
|
||||
// Stores all relevant information for a single texture
|
||||
// assumed to have ownership of all objects referred to -
|
||||
// will delete objects when being replaced or if object is destroyed.
|
||||
class LLLocalTextureObject
|
||||
{
|
||||
public:
|
||||
LLLocalTextureObject();
|
||||
LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id);
|
||||
LLLocalTextureObject(const LLLocalTextureObject& lto);
|
||||
~LLLocalTextureObject();
|
||||
|
||||
LLViewerFetchedTexture* getImage() const;
|
||||
LLTexLayer* getTexLayer(U32 index) const;
|
||||
LLTexLayer* getTexLayer(const std::string &name);
|
||||
U32 getNumTexLayers() const;
|
||||
LLUUID getID() const;
|
||||
S32 getDiscard() const;
|
||||
BOOL getBakedReady() const;
|
||||
|
||||
void setImage(LLViewerFetchedTexture* new_image);
|
||||
BOOL setTexLayer(LLTexLayer *new_tex_layer, U32 index);
|
||||
BOOL addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable);
|
||||
BOOL addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable);
|
||||
BOOL removeTexLayer(U32 index);
|
||||
|
||||
void setID(LLUUID new_id);
|
||||
void setDiscard(S32 new_discard);
|
||||
void setBakedReady(BOOL ready);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
LLPointer<LLViewerFetchedTexture> mImage;
|
||||
// NOTE: LLLocalTextureObject should be the exclusive owner of mTexEntry and mTexLayer
|
||||
// using shared pointers here only for smart assignment & cleanup
|
||||
// do NOT create new shared pointers to these objects, or keep pointers to them around
|
||||
typedef std::vector<LLTexLayer*> tex_layer_vec_t;
|
||||
tex_layer_vec_t mTexLayers;
|
||||
|
||||
LLUUID mID;
|
||||
|
||||
BOOL mIsBakedReady;
|
||||
S32 mDiscard;
|
||||
};
|
||||
|
||||
#endif // LL_LOCALTEXTUREOBJECT_H
|
||||
|
||||
@@ -110,7 +110,7 @@ void LLMorphView::initialize()
|
||||
//-----------------------------------------------------------------------------
|
||||
void LLMorphView::shutdown()
|
||||
{
|
||||
LLVOAvatar::onCustomizeEnd();
|
||||
LLVOAvatarSelf::onCustomizeEnd();
|
||||
|
||||
if (isAgentAvatarValid())
|
||||
{
|
||||
|
||||
@@ -81,21 +81,21 @@ LLFloaterMove::LLFloaterMove(const LLSD& key)
|
||||
|
||||
mTurnLeftButton = getChild<LLButton>("turn left btn");
|
||||
mTurnLeftButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
|
||||
mTurnLeftButton->setHeldDownCallback( turnLeft );
|
||||
mTurnLeftButton->setHeldDownCallback( boost::bind(&LLFloaterMove::turnLeft, this) );
|
||||
|
||||
mTurnRightButton = getChild<LLButton>("turn right btn");
|
||||
mTurnRightButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
|
||||
mTurnRightButton->setHeldDownCallback( turnRight );
|
||||
mTurnRightButton->setHeldDownCallback( boost::bind(&LLFloaterMove::turnRight, this) );
|
||||
|
||||
mMoveUpButton = getChild<LLButton>("move up btn");
|
||||
childSetAction("move up btn",moveUp,NULL);
|
||||
mMoveUpButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
|
||||
mMoveUpButton->setHeldDownCallback( moveUp );
|
||||
mMoveUpButton->setHeldDownCallback( boost::bind(&LLFloaterMove::moveUp, this) );
|
||||
|
||||
mMoveDownButton = getChild<LLButton>("move down btn");
|
||||
childSetAction("move down btn",moveDown,NULL);
|
||||
mMoveDownButton->setHeldDownDelay(MOVE_BUTTON_DELAY);
|
||||
mMoveDownButton->setHeldDownCallback( moveDown );
|
||||
mMoveDownButton->setHeldDownCallback( boost::bind(&LLFloaterMove::moveDown, this) );
|
||||
}
|
||||
|
||||
// virtual
|
||||
|
||||
@@ -664,7 +664,7 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec
|
||||
LLVector3d mypos = gAgent.getPositionGlobal();
|
||||
LLVector3d position = mClosestAgentPosition;
|
||||
|
||||
if ( LLFloaterAvatarList::getInstance() )
|
||||
if ( LLFloaterAvatarList::instanceExists() )
|
||||
{
|
||||
LLAvatarListEntry *ent = LLFloaterAvatarList::getInstance()->getAvatarEntry(mClosestAgentToCursor);
|
||||
if ( NULL != ent )
|
||||
|
||||
153
indra/newview/lloutfitobserver.cpp
Normal file
153
indra/newview/lloutfitobserver.cpp
Normal file
@@ -0,0 +1,153 @@
|
||||
/**
|
||||
* @file lloutfitobserver.cpp
|
||||
* @brief Outfit observer facade.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "llappearancemgr.h"
|
||||
#include "lloutfitobserver.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llviewerinventory.h"
|
||||
|
||||
LLOutfitObserver::LLOutfitObserver() :
|
||||
mCOFLastVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)
|
||||
{
|
||||
mItemNameHash.finalize();
|
||||
gInventory.addObserver(this);
|
||||
}
|
||||
|
||||
LLOutfitObserver::~LLOutfitObserver()
|
||||
{
|
||||
if (gInventory.containsObserver(this))
|
||||
{
|
||||
gInventory.removeObserver(this);
|
||||
}
|
||||
}
|
||||
|
||||
void LLOutfitObserver::changed(U32 mask)
|
||||
{
|
||||
if (!gInventory.isInventoryUsable())
|
||||
return;
|
||||
|
||||
checkCOF();
|
||||
|
||||
checkBaseOutfit();
|
||||
}
|
||||
|
||||
// static
|
||||
S32 LLOutfitObserver::getCategoryVersion(const LLUUID& cat_id)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
|
||||
if (!cat)
|
||||
return LLViewerInventoryCategory::VERSION_UNKNOWN;
|
||||
|
||||
return cat->getVersion();
|
||||
}
|
||||
|
||||
// static
|
||||
const std::string& LLOutfitObserver::getCategoryName(const LLUUID& cat_id)
|
||||
{
|
||||
LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
|
||||
if (!cat)
|
||||
return LLStringUtil::null;
|
||||
|
||||
return cat->getName();
|
||||
}
|
||||
|
||||
bool LLOutfitObserver::checkCOF()
|
||||
{
|
||||
LLUUID cof = LLAppearanceMgr::getInstance()->getCOF();
|
||||
if (cof.isNull())
|
||||
return false;
|
||||
|
||||
bool cof_changed = false;
|
||||
LLMD5 item_name_hash = gInventory.hashDirectDescendentNames(cof);
|
||||
if (item_name_hash != mItemNameHash)
|
||||
{
|
||||
cof_changed = true;
|
||||
mItemNameHash = item_name_hash;
|
||||
}
|
||||
|
||||
S32 cof_version = getCategoryVersion(cof);
|
||||
if (cof_version != mCOFLastVersion)
|
||||
{
|
||||
cof_changed = true;
|
||||
mCOFLastVersion = cof_version;
|
||||
}
|
||||
|
||||
if (!cof_changed)
|
||||
return false;
|
||||
|
||||
// dirtiness state should be updated before sending signal
|
||||
LLAppearanceMgr::getInstance()->updateIsDirty();
|
||||
mCOFChanged();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLOutfitObserver::checkBaseOutfit()
|
||||
{
|
||||
LLUUID baseoutfit_id =
|
||||
LLAppearanceMgr::getInstance()->getBaseOutfitUUID();
|
||||
|
||||
if (baseoutfit_id == mBaseOutfitId)
|
||||
{
|
||||
if (baseoutfit_id.isNull())
|
||||
return;
|
||||
|
||||
const S32 baseoutfit_ver = getCategoryVersion(baseoutfit_id);
|
||||
const std::string& baseoutfit_name = getCategoryName(baseoutfit_id);
|
||||
|
||||
if (baseoutfit_ver == mBaseOutfitLastVersion
|
||||
// renaming category doesn't change version, so it's need to check it
|
||||
&& baseoutfit_name == mLastBaseOutfitName)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
mBaseOutfitId = baseoutfit_id;
|
||||
mBOFReplaced();
|
||||
|
||||
if (baseoutfit_id.isNull())
|
||||
return;
|
||||
}
|
||||
|
||||
mBaseOutfitLastVersion = getCategoryVersion(mBaseOutfitId);
|
||||
mLastBaseOutfitName = getCategoryName(baseoutfit_id);
|
||||
|
||||
LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance();
|
||||
// dirtiness state should be updated before sending signal
|
||||
app_mgr.updateIsDirty();
|
||||
mBOFChanged();
|
||||
|
||||
if (mLastOutfitDirtiness != app_mgr.isOutfitDirty())
|
||||
{
|
||||
if(!app_mgr.isOutfitDirty())
|
||||
{
|
||||
mCOFSaved();
|
||||
}
|
||||
mLastOutfitDirtiness = app_mgr.isOutfitDirty();
|
||||
}
|
||||
}
|
||||
96
indra/newview/lloutfitobserver.h
Normal file
96
indra/newview/lloutfitobserver.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/**
|
||||
* @file lloutfitobserver.h
|
||||
* @brief Outfit observer facade.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2010&license=viewerlgpl$
|
||||
* Second Life Viewer Source Code
|
||||
* Copyright (C) 2010, Linden Research, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation;
|
||||
* version 2.1 of the License only.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
#ifndef LL_OUTFITOBSERVER_H
|
||||
#define LL_OUTFITOBSERVER_H
|
||||
|
||||
#include "llsingleton.h"
|
||||
#include "llmd5.h"
|
||||
|
||||
/**
|
||||
* Outfit observer facade that provides simple possibility to subscribe on
|
||||
* BOF(base outfit) replaced, BOF changed, COF(current outfit) changed events.
|
||||
*/
|
||||
class LLOutfitObserver: public LLInventoryObserver, public LLSingleton<LLOutfitObserver>
|
||||
{
|
||||
public:
|
||||
virtual ~LLOutfitObserver();
|
||||
|
||||
friend class LLSingleton<LLOutfitObserver>;
|
||||
|
||||
virtual void changed(U32 mask);
|
||||
|
||||
void notifyOutfitLockChanged() { mOutfitLockChanged(); }
|
||||
|
||||
typedef boost::signals2::signal<void (void)> signal_t;
|
||||
|
||||
void addBOFReplacedCallback(const signal_t::slot_type& cb) { mBOFReplaced.connect(cb); }
|
||||
|
||||
void addBOFChangedCallback(const signal_t::slot_type& cb) { mBOFChanged.connect(cb); }
|
||||
|
||||
void addCOFChangedCallback(const signal_t::slot_type& cb) { mCOFChanged.connect(cb); }
|
||||
|
||||
void addCOFSavedCallback(const signal_t::slot_type& cb) { mCOFSaved.connect(cb); }
|
||||
|
||||
void addOutfitLockChangedCallback(const signal_t::slot_type& cb) { mOutfitLockChanged.connect(cb); }
|
||||
|
||||
protected:
|
||||
LLOutfitObserver();
|
||||
|
||||
/** Get a version of an inventory category specified by its UUID */
|
||||
static S32 getCategoryVersion(const LLUUID& cat_id);
|
||||
|
||||
static const std::string& getCategoryName(const LLUUID& cat_id);
|
||||
|
||||
bool checkCOF();
|
||||
|
||||
void checkBaseOutfit();
|
||||
|
||||
//last version number of a COF category
|
||||
S32 mCOFLastVersion;
|
||||
|
||||
LLUUID mBaseOutfitId;
|
||||
|
||||
S32 mBaseOutfitLastVersion;
|
||||
std::string mLastBaseOutfitName;
|
||||
|
||||
bool mLastOutfitDirtiness;
|
||||
|
||||
LLMD5 mItemNameHash;
|
||||
|
||||
private:
|
||||
signal_t mBOFReplaced;
|
||||
signal_t mBOFChanged;
|
||||
signal_t mCOFChanged;
|
||||
signal_t mCOFSaved;
|
||||
|
||||
/**
|
||||
* Signal for changing state of outfit lock.
|
||||
*/
|
||||
signal_t mOutfitLockChanged;
|
||||
};
|
||||
|
||||
#endif /* LL_OUTFITOBSERVER_H */
|
||||
@@ -587,7 +587,7 @@ void LLPanelAvatarSecondLife::onClickPartnerInfo(void *data)
|
||||
if (self->mPartnerID.notNull())
|
||||
{
|
||||
LLFloaterAvatarInfo::showFromProfile(self->mPartnerID,
|
||||
self->getScreenRect());
|
||||
self->calcScreenRect());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -713,19 +713,19 @@ void LLPanelAvatarWeb::processProperties(void* data, EAvatarProcessorType type)
|
||||
|
||||
BOOL LLPanelAvatarClassified::postBuild(void)
|
||||
{
|
||||
childSetAction("New...",onClickNew,NULL);
|
||||
childSetAction("Delete...",onClickDelete,NULL);
|
||||
childSetAction("New...",onClickNew,this);
|
||||
childSetAction("Delete...",onClickDelete,this);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLPanelAvatarPicks::postBuild(void)
|
||||
{
|
||||
childSetAction("New...",onClickNew,NULL);
|
||||
childSetAction("Delete...",onClickDelete,NULL);
|
||||
childSetAction("New...",onClickNew,this);
|
||||
childSetAction("Delete...",onClickDelete,this);
|
||||
|
||||
//For pick import and export - RK
|
||||
childSetAction("Import...",onClickImport,NULL);
|
||||
childSetAction("Export...",onClickExport,NULL);
|
||||
childSetAction("Import...",onClickImport,this);
|
||||
childSetAction("Export...",onClickExport,this);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
@@ -255,14 +255,14 @@ BOOL LLPanelClassified::postBuild()
|
||||
mNameEditor = getChild<LLLineEditor>("given_name_editor");
|
||||
mNameEditor->setMaxTextLength(DB_PARCEL_NAME_LEN);
|
||||
mNameEditor->setCommitOnFocusLost(TRUE);
|
||||
mNameEditor->setFocusReceivedCallback(focusReceived, this);
|
||||
mNameEditor->setFocusReceivedCallback(boost::bind(focusReceived, _1, this));
|
||||
mNameEditor->setCommitCallback(onCommitAny);
|
||||
mNameEditor->setCallbackUserData(this);
|
||||
mNameEditor->setPrevalidate( LLLineEditor::prevalidateASCII );
|
||||
|
||||
mDescEditor = getChild<LLTextEditor>("desc_editor");
|
||||
mDescEditor->setCommitOnFocusLost(TRUE);
|
||||
mDescEditor->setFocusReceivedCallback(focusReceived, this);
|
||||
mDescEditor->setFocusReceivedCallback(boost::bind(focusReceived, _1, this));
|
||||
mDescEditor->setCommitCallback(onCommitAny);
|
||||
mDescEditor->setCallbackUserData(this);
|
||||
mDescEditor->setTabsToNextField(TRUE);
|
||||
@@ -270,22 +270,18 @@ BOOL LLPanelClassified::postBuild()
|
||||
mLocationEditor = getChild<LLLineEditor>("location_editor");
|
||||
|
||||
mSetBtn = getChild<LLButton>( "set_location_btn");
|
||||
mSetBtn->setClickedCallback(onClickSet);
|
||||
mSetBtn->setCallbackUserData(this);
|
||||
mSetBtn->setClickedCallback(boost::bind(&LLPanelClassified::onClickSet, this));
|
||||
|
||||
mTeleportBtn = getChild<LLButton>( "classified_teleport_btn");
|
||||
mTeleportBtn->setClickedCallback(onClickTeleport);
|
||||
mTeleportBtn->setCallbackUserData(this);
|
||||
mTeleportBtn->setClickedCallback(boost::bind(&LLPanelClassified::onClickTeleport, this));
|
||||
|
||||
mMapBtn = getChild<LLButton>( "classified_map_btn");
|
||||
mMapBtn->setClickedCallback(onClickMap);
|
||||
mMapBtn->setCallbackUserData(this);
|
||||
mMapBtn->setClickedCallback(boost::bind(&LLPanelClassified::onClickMap, this));
|
||||
|
||||
if(mInFinder)
|
||||
{
|
||||
mProfileBtn = getChild<LLButton>( "classified_profile_btn");
|
||||
mProfileBtn->setClickedCallback(onClickProfile);
|
||||
mProfileBtn->setCallbackUserData(this);
|
||||
mProfileBtn->setClickedCallback(boost::bind(&LLPanelClassified::onClickProfile, this));
|
||||
}
|
||||
|
||||
mCategoryCombo = getChild<LLComboBox>( "classified_category_combo");
|
||||
@@ -319,7 +315,7 @@ BOOL LLPanelClassified::postBuild()
|
||||
}
|
||||
|
||||
mUpdateBtn = getChild<LLButton>("classified_update_btn");
|
||||
mUpdateBtn->setClickedCallback(onClickUpdate);
|
||||
mUpdateBtn->setClickedCallback(boost::bind(&LLPanelClassified::onClickUpdate, this));
|
||||
mUpdateBtn->setCallbackUserData(this);
|
||||
|
||||
if (!mInFinder)
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
#include "lltool.h"
|
||||
#include "lltoolmgr.h"
|
||||
#include "lltoolcomp.h"
|
||||
#include "llpanelinventory.h"
|
||||
#include "llpanelobjectinventory.h"
|
||||
// [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c)
|
||||
#include "rlvhandler.h"
|
||||
// [/RLVa:KB]
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include "llpanel.h"
|
||||
|
||||
class LLButton;
|
||||
class LLPanelInventory;
|
||||
class LLPanelObjectInventory;
|
||||
class LLViewerObject;
|
||||
class LLCheckBoxCtrl;
|
||||
class LLSpinCtrl;
|
||||
@@ -58,7 +58,7 @@ protected:
|
||||
void getState(LLViewerObject *object);
|
||||
|
||||
public:
|
||||
LLPanelInventory* mPanelInventory;
|
||||
LLPanelObjectInventory* mPanelInventory;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -89,20 +89,16 @@ BOOL LLPanelEvent::postBuild()
|
||||
mTBCover = getChild<LLTextBox>("event_cover");
|
||||
|
||||
mTeleportBtn = getChild<LLButton>( "teleport_btn");
|
||||
mTeleportBtn->setClickedCallback(onClickTeleport);
|
||||
mTeleportBtn->setCallbackUserData(this);
|
||||
mTeleportBtn->setClickedCallback(boost::bind(&LLPanelEvent::onClickTeleport,this));
|
||||
|
||||
mMapBtn = getChild<LLButton>( "map_btn");
|
||||
mMapBtn->setClickedCallback(onClickMap);
|
||||
mMapBtn->setCallbackUserData(this);
|
||||
mMapBtn->setClickedCallback(boost::bind(&LLPanelEvent::onClickMap,this));
|
||||
|
||||
mNotifyBtn = getChild<LLButton>( "notify_btn");
|
||||
mNotifyBtn->setClickedCallback(onClickNotify);
|
||||
mNotifyBtn->setCallbackUserData(this);
|
||||
mNotifyBtn->setClickedCallback(boost::bind(&LLPanelEvent::onClickNotify,this));
|
||||
|
||||
mCreateEventBtn = getChild<LLButton>( "create_event_btn");
|
||||
mCreateEventBtn->setClickedCallback(onClickCreateEvent);
|
||||
mCreateEventBtn->setCallbackUserData(this);
|
||||
mCreateEventBtn->setClickedCallback(boost::bind(&LLPanelEvent::onClickCreateEvent,this));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -72,8 +72,7 @@ BOOL LLPanelGroupTab::postBuild()
|
||||
LLButton* button = getChild<LLButton>("help_button");
|
||||
if (button)
|
||||
{
|
||||
button->setClickedCallback(onClickHelp);
|
||||
button->setCallbackUserData(this);
|
||||
button->setClickedCallback(boost::bind(&LLPanelGroupTab::onClickHelp,this));
|
||||
}
|
||||
|
||||
mHelpText = getString("help_text");
|
||||
@@ -267,23 +266,21 @@ BOOL LLPanelGroup::postBuild()
|
||||
LLButton* button = getChild<LLButton>("btn_ok");
|
||||
if (button)
|
||||
{
|
||||
button->setClickedCallback(onBtnOK);
|
||||
button->setCallbackUserData(this);
|
||||
button->setClickedCallback(boost::bind(&LLPanelGroup::onBtnOK,this));
|
||||
button->setVisible(mAllowEdit);
|
||||
}
|
||||
|
||||
button = getChild<LLButton>("btn_cancel");
|
||||
if (button)
|
||||
{
|
||||
button->setClickedCallback(onBtnCancel);
|
||||
button->setCallbackUserData(this);
|
||||
button->setClickedCallback(boost::bind(&LLPanelGroup::onBtnCancel,this));
|
||||
button->setVisible(mAllowEdit);
|
||||
}
|
||||
|
||||
button = getChild<LLButton>("btn_apply");
|
||||
if (button)
|
||||
{
|
||||
button->setClickedCallback(onBtnApply);
|
||||
button->setClickedCallback(boost::bind(&LLPanelGroup::onBtnApply,this));
|
||||
button->setVisible(mAllowEdit);
|
||||
button->setEnabled(FALSE);
|
||||
|
||||
@@ -293,8 +290,7 @@ BOOL LLPanelGroup::postBuild()
|
||||
button = getChild<LLButton>("btn_refresh");
|
||||
if (button)
|
||||
{
|
||||
button->setClickedCallback(onBtnRefresh);
|
||||
button->setCallbackUserData(this);
|
||||
button->setClickedCallback(boost::bind(&LLPanelGroup::onBtnRefresh,this));
|
||||
button->setVisible(mAllowEdit);
|
||||
}
|
||||
|
||||
|
||||
@@ -127,37 +127,36 @@ BOOL LLPanelGroupGeneral::postBuild()
|
||||
if(mEditCharter)
|
||||
{
|
||||
mEditCharter->setCommitCallback(onCommitAny);
|
||||
mEditCharter->setFocusReceivedCallback(onFocusEdit, this);
|
||||
mEditCharter->setFocusChangedCallback(onFocusEdit, this);
|
||||
mEditCharter->setFocusReceivedCallback(boost::bind(&LLPanelGroupGeneral::onFocusEdit, this));
|
||||
mEditCharter->setFocusChangedCallback(boost::bind(&LLPanelGroupGeneral::onFocusEdit, this));
|
||||
mEditCharter->setCallbackUserData(this);
|
||||
}
|
||||
|
||||
mBtnJoinGroup = getChild<LLButton>("join_button", recurse);
|
||||
if ( mBtnJoinGroup )
|
||||
{
|
||||
mBtnJoinGroup->setClickedCallback(onClickJoin);
|
||||
mBtnJoinGroup->setCallbackUserData(this);
|
||||
mBtnJoinGroup->setClickedCallback(boost::bind(&LLPanelGroupGeneral::onClickJoin, this));
|
||||
}
|
||||
|
||||
mBtnInfo = getChild<LLButton>("info_button", recurse);
|
||||
if ( mBtnInfo )
|
||||
{
|
||||
mBtnInfo->setClickedCallback(onClickInfo);
|
||||
mBtnInfo->setCallbackUserData(this);
|
||||
mBtnInfo->setClickedCallback(boost::bind(&LLPanelGroupGeneral::onClickInfo, this));
|
||||
}
|
||||
|
||||
LLTextBox* founder = getChild<LLTextBox>("founder_name");
|
||||
if (founder)
|
||||
{
|
||||
mFounderName = new LLNameBox(founder->getName(),founder->getRect(),LLUUID::null,FALSE,founder->getFont(),founder->getMouseOpaque());
|
||||
removeChild(founder, TRUE);
|
||||
removeChild(founder);
|
||||
delete founder;
|
||||
addChild(mFounderName);
|
||||
}
|
||||
|
||||
mListVisibleMembers = getChild<LLNameListCtrl>("visible_members", recurse);
|
||||
if (mListVisibleMembers)
|
||||
{
|
||||
mListVisibleMembers->setDoubleClickCallback(openProfile);
|
||||
mListVisibleMembers->setDoubleClickCallback(&LLPanelGroupGeneral::openProfile);
|
||||
mListVisibleMembers->setCallbackUserData(this);
|
||||
}
|
||||
|
||||
@@ -165,7 +164,7 @@ BOOL LLPanelGroupGeneral::postBuild()
|
||||
mCtrlShowInGroupList = getChild<LLCheckBoxCtrl>("show_in_group_list", recurse);
|
||||
if (mCtrlShowInGroupList)
|
||||
{
|
||||
mCtrlShowInGroupList->setCommitCallback(onCommitAny);
|
||||
mCtrlShowInGroupList->setCommitCallback(&LLPanelGroupGeneral::onCommitAny);
|
||||
mCtrlShowInGroupList->setCallbackUserData(this);
|
||||
}
|
||||
|
||||
@@ -279,15 +278,12 @@ BOOL LLPanelGroupGeneral::postBuild()
|
||||
return LLPanelGroupTab::postBuild();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelGroupGeneral::onFocusEdit(LLFocusableElement* ctrl, void* data)
|
||||
void LLPanelGroupGeneral::onFocusEdit()
|
||||
{
|
||||
LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data;
|
||||
self->updateChanged();
|
||||
self->notifyObservers();
|
||||
updateChanged();
|
||||
notifyObservers();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelGroupGeneral::onCommitAny(LLUICtrl* ctrl, void* data)
|
||||
{
|
||||
LLPanelGroupGeneral* self = (LLPanelGroupGeneral*)data;
|
||||
|
||||
@@ -67,7 +67,7 @@ public:
|
||||
virtual void draw();
|
||||
|
||||
private:
|
||||
static void onFocusEdit(LLFocusableElement* ctrl, void* data);
|
||||
void onFocusEdit();
|
||||
static void onCommitAny(LLUICtrl* ctrl, void* data);
|
||||
static void onCommitUserOnly(LLUICtrl* ctrl, void* data);
|
||||
static void onCommitTitle(LLUICtrl* ctrl, void* data);
|
||||
|
||||
@@ -527,17 +527,14 @@ BOOL LLPanelGroupInvite::postBuild()
|
||||
{
|
||||
// default to opening avatarpicker automatically
|
||||
// (*impl::callbackClickAdd)((void*)this);
|
||||
button->setClickedCallback(impl::callbackClickAdd);
|
||||
button->setCallbackUserData(this);
|
||||
button->setClickedCallback(boost::bind(&impl::callbackClickAdd, this));
|
||||
}
|
||||
|
||||
mImplementation->mRemoveButton =
|
||||
getChild<LLButton>("remove_button", recurse);
|
||||
if ( mImplementation->mRemoveButton )
|
||||
{
|
||||
mImplementation->mRemoveButton->
|
||||
setClickedCallback(impl::callbackClickRemove);
|
||||
mImplementation->mRemoveButton->setCallbackUserData(mImplementation);
|
||||
mImplementation->mRemoveButton->setClickedCallback(boost::bind(&impl::callbackClickRemove, mImplementation));
|
||||
mImplementation->mRemoveButton->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
@@ -545,17 +542,14 @@ BOOL LLPanelGroupInvite::postBuild()
|
||||
getChild<LLButton>("ok_button", recurse);
|
||||
if ( mImplementation->mOKButton )
|
||||
{
|
||||
mImplementation->mOKButton->
|
||||
setClickedCallback(impl::callbackClickOK);
|
||||
mImplementation->mOKButton->setCallbackUserData(mImplementation);
|
||||
mImplementation->mOKButton->setClickedCallback(boost::bind(&impl::callbackClickOK, mImplementation));
|
||||
mImplementation->mOKButton->setEnabled(FALSE);
|
||||
}
|
||||
|
||||
button = getChild<LLButton>("cancel_button", recurse);
|
||||
if ( button )
|
||||
{
|
||||
button->setClickedCallback(impl::callbackClickCancel);
|
||||
button->setCallbackUserData(mImplementation);
|
||||
button->setClickedCallback(boost::bind(&impl::callbackClickCancel,mImplementation));
|
||||
}
|
||||
|
||||
mImplementation->mOwnerWarning = getString("confirm_invite_owner_str");
|
||||
|
||||
@@ -654,7 +654,7 @@ BOOL LLPanelGroupLandMoney::postBuild()
|
||||
|
||||
if ( mImplementationp->mMapButtonp )
|
||||
{
|
||||
mImplementationp->mMapButtonp->setClickedCallback(LLPanelGroupLandMoney::impl::mapCallback, mImplementationp);
|
||||
mImplementationp->mMapButtonp->setClickedCallback(boost::bind(&LLPanelGroupLandMoney::impl::mapCallback, mImplementationp));
|
||||
}
|
||||
|
||||
if ( mImplementationp->mGroupOverLimitTextp )
|
||||
|
||||
@@ -220,13 +220,11 @@ BOOL LLPanelGroupNotices::postBuild()
|
||||
mNoticesList->setCallbackUserData(this);
|
||||
|
||||
mBtnNewMessage = getChild<LLButton>("create_new_notice",recurse);
|
||||
mBtnNewMessage->setClickedCallback(onClickNewMessage);
|
||||
mBtnNewMessage->setCallbackUserData(this);
|
||||
mBtnNewMessage->setClickedCallback(boost::bind(&LLPanelGroupNotices::onClickNewMessage,this));
|
||||
mBtnNewMessage->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_NOTICES_SEND));
|
||||
|
||||
mBtnGetPastNotices = getChild<LLButton>("refresh_notices",recurse);
|
||||
mBtnGetPastNotices->setClickedCallback(onClickRefreshNotices);
|
||||
mBtnGetPastNotices->setCallbackUserData(this);
|
||||
mBtnGetPastNotices->setClickedCallback(boost::bind(&LLPanelGroupNotices::onClickRefreshNotices,this));
|
||||
|
||||
// Create
|
||||
mCreateSubject = getChild<LLLineEditor>("create_subject",recurse);
|
||||
@@ -240,12 +238,10 @@ BOOL LLPanelGroupNotices::postBuild()
|
||||
mCreateInventoryIcon->setVisible(FALSE);
|
||||
|
||||
mBtnSendMessage = getChild<LLButton>("send_notice",recurse);
|
||||
mBtnSendMessage->setClickedCallback(onClickSendMessage);
|
||||
mBtnSendMessage->setCallbackUserData(this);
|
||||
mBtnSendMessage->setClickedCallback(boost::bind(&LLPanelGroupNotices::onClickSendMessage,this));
|
||||
|
||||
mBtnRemoveAttachment = getChild<LLButton>("remove_attachment",recurse);
|
||||
mBtnRemoveAttachment->setClickedCallback(onClickRemoveAttachment);
|
||||
mBtnRemoveAttachment->setCallbackUserData(this);
|
||||
mBtnRemoveAttachment->setClickedCallback(boost::bind(&LLPanelGroupNotices::onClickRemoveAttachment,this));
|
||||
mBtnRemoveAttachment->setEnabled(FALSE);
|
||||
|
||||
// View
|
||||
@@ -261,8 +257,7 @@ BOOL LLPanelGroupNotices::postBuild()
|
||||
mViewInventoryIcon->setVisible(FALSE);
|
||||
|
||||
mBtnOpenAttachment = getChild<LLButton>("open_attachment",recurse);
|
||||
mBtnOpenAttachment->setClickedCallback(onClickOpenAttachment);
|
||||
mBtnOpenAttachment->setCallbackUserData(this);
|
||||
mBtnOpenAttachment->setClickedCallback(boost::bind(&LLPanelGroupNotices::onClickOpenAttachment,this));
|
||||
|
||||
mNoNoticesStr = getString("no_notices_text");
|
||||
|
||||
@@ -278,7 +273,8 @@ BOOL LLPanelGroupNotices::postBuild()
|
||||
target->setToolTip(dtv->getToolTip());
|
||||
|
||||
mPanelCreateNotice->addChild(target);
|
||||
mPanelCreateNotice->removeChild(dtv, TRUE);
|
||||
mPanelCreateNotice->removeChild(dtv);
|
||||
delete dtv;
|
||||
|
||||
arrangeNoticeView(VIEW_PAST_NOTICE);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user