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:
Siana Gearz
2012-03-28 22:27:45 +02:00
264 changed files with 27606 additions and 15368 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -30,7 +30,7 @@
#include "roles_constants.h"
#include "llviewerregion.h"
#include "llpanelinventory.h"
#include "llpanelobjectinventory.h"
#include "llinventorybridge.h"
#include "llboost.h"

View File

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

View File

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

View File

@@ -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(&notifyCallback, 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(&notifyCallback, ctrl))));
else
ctrl->setCommitCallback(0);
floater->mNotices.erase(ctrl);
}
}
}

View File

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

View File

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

View File

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

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

View 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

File diff suppressed because it is too large Load Diff

View 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

View File

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

View File

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

View File

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

View File

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

View File

@@ -28,7 +28,7 @@
#ifndef LL_LLATTACHMENTSMGR_H
#define LL_LLATTACHMENTSMGR_H
#include "llmemory.h"
#include "llsingleton.h"
class LLViewerInventoryItem;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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$
*/

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View 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

View File

@@ -110,7 +110,7 @@ void LLMorphView::initialize()
//-----------------------------------------------------------------------------
void LLMorphView::shutdown()
{
LLVOAvatar::onCustomizeEnd();
LLVOAvatarSelf::onCustomizeEnd();
if (isAgentAvatarValid())
{

View File

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

View File

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

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

View 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 */

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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