automated merge

master
Roxie Linden 2010-04-23 13:24:09 -07:00
commit a42dcc3f5e
93 changed files with 2931 additions and 914 deletions

View File

@ -35,6 +35,7 @@ set(llcommon_SOURCE_FILES
llbase32.cpp
llbase64.cpp
llcommon.cpp
llcommonutils.cpp
llcoros.cpp
llcrc.cpp
llcriticaldamp.cpp
@ -124,6 +125,7 @@ set(llcommon_HEADER_FILES
llchat.h
llclickaction.h
llcommon.h
llcommonutils.h
llcoros.h
llcrc.h
llcriticaldamp.h

View File

@ -0,0 +1,61 @@
/**
* @file llcommonutils.h
* @brief Commin utils
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llcommonutils.h"
void LLCommonUtils::computeDifference(
const uuid_vec_t& vnew,
const uuid_vec_t& vcur,
uuid_vec_t& vadded,
uuid_vec_t& vremoved)
{
uuid_vec_t vnew_copy(vnew);
uuid_vec_t vcur_copy(vcur);
std::sort(vnew_copy.begin(), vnew_copy.end());
std::sort(vcur_copy.begin(), vcur_copy.end());
size_t maxsize = llmax(vnew_copy.size(), vcur_copy.size());
vadded.resize(maxsize);
vremoved.resize(maxsize);
uuid_vec_t::iterator it;
// what was removed
it = set_difference(vcur_copy.begin(), vcur_copy.end(), vnew_copy.begin(), vnew_copy.end(), vremoved.begin());
vremoved.erase(it, vremoved.end());
// what was added
it = set_difference(vnew_copy.begin(), vnew_copy.end(), vcur_copy.begin(), vcur_copy.end(), vadded.begin());
vadded.erase(it, vadded.end());
}
// EOF

View File

@ -0,0 +1,51 @@
/**
* @file llcommonutils.h
* @brief Common utils
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLCOMMONUTILS_H
#define LL_LLCOMMONUTILS_H
namespace LLCommonUtils
{
/**
* Computes difference between 'vnew' and 'vcur' vectors.
* Items present in 'vnew' and missing in 'vcur' are treated as added and are copied into 'vadded'
* Items missing in 'vnew' and present in 'vcur' are treated as removed and are copied into 'vremoved'
*/
LL_COMMON_API void computeDifference(
const uuid_vec_t& vnew,
const uuid_vec_t& vcur,
uuid_vec_t& vadded,
uuid_vec_t& vremoved);
};
#endif //LL_LLCOMMONUTILS_H
// EOF

View File

@ -332,11 +332,31 @@ void LLAccordionCtrl::addCollapsibleCtrl(LLView* view)
if(std::find(getChildList()->begin(),getChildList()->end(),accordion_tab) == getChildList()->end())
addChild(accordion_tab);
mAccordionTabs.push_back(accordion_tab);
accordion_tab->setDropDownStateChangedCallback( boost::bind(&LLAccordionCtrl::onCollapseCtrlCloseOpen, this, mAccordionTabs.size() - 1) );
}
void LLAccordionCtrl::removeCollapsibleCtrl(LLView* view)
{
LLAccordionCtrlTab* accordion_tab = dynamic_cast<LLAccordionCtrlTab*>(view);
if(!accordion_tab)
return;
if(std::find(getChildList()->begin(),getChildList()->end(),accordion_tab) != getChildList()->end())
removeChild(accordion_tab);
for (std::vector<LLAccordionCtrlTab*>::iterator iter = mAccordionTabs.begin();
iter != mAccordionTabs.end(); ++iter)
{
if (accordion_tab == (*iter))
{
mAccordionTabs.erase(iter);
break;
}
}
}
void LLAccordionCtrl::arrangeSinge()
{
S32 panel_left = BORDER_MARGIN; // Margin from left side of Splitter

View File

@ -92,6 +92,7 @@ public:
virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
void addCollapsibleCtrl(LLView* view);
void removeCollapsibleCtrl(LLView* view);
void arrange();

View File

@ -425,6 +425,9 @@ bool LLAccordionCtrlTab::addChild(LLView* child, S32 tab_group)
setDisplayChildren(getDisplayChildren());
}
if (!mContainerPanel)
mContainerPanel = findContainerView();
return res;
}

View File

@ -1003,6 +1003,11 @@ void LLButton::setImageDisabledSelected(LLPointer<LLUIImage> image)
mFadeWhenDisabled = TRUE;
}
void LLButton::setImagePressed(LLPointer<LLUIImage> image)
{
mImagePressed = image;
}
void LLButton::setImageHoverSelected(LLPointer<LLUIImage> image)
{
mImageHoverSelected = image;

View File

@ -246,6 +246,7 @@ public:
void setImageHoverUnselected(LLPointer<LLUIImage> image);
void setImageDisabled(LLPointer<LLUIImage> image);
void setImageDisabledSelected(LLPointer<LLUIImage> image);
void setImagePressed(LLPointer<LLUIImage> image);
void setCommitOnReturn(BOOL commit) { mCommitOnReturn = commit; }
BOOL getCommitOnReturn() const { return mCommitOnReturn; }

View File

@ -73,6 +73,7 @@ public:
std::string getImageName() const;
void setColor(const LLColor4& color) { mColor = color; }
void setImage(LLPointer<LLUIImage> image) { mImagep = image; }
private:
void setIconImageDrawSize() ;

View File

@ -48,122 +48,38 @@
const std::string NOTIFICATION_PERSIST_VERSION = "0.93";
// local channel for notification history
class LLNotificationHistoryChannel : public LLNotificationChannel
// Local channel for persistent notifications
// Stores only persistent notifications.
// Class users can use connectChanged() to process persistent notifications
// (see LLNotificationStorage for example).
class LLPersistentNotificationChannel : public LLNotificationChannel
{
LOG_CLASS(LLNotificationHistoryChannel);
LOG_CLASS(LLPersistentNotificationChannel);
public:
LLNotificationHistoryChannel(const std::string& filename) :
LLNotificationChannel("History", "Visible", &historyFilter, LLNotificationComparators::orderByUUID()),
mFileName(filename)
LLPersistentNotificationChannel() :
LLNotificationChannel("Persistent", "Visible", &notificationFilter, LLNotificationComparators::orderByUUID())
{
connectChanged(boost::bind(&LLNotificationHistoryChannel::historyHandler, this, _1));
loadPersistentNotifications();
}
private:
bool historyHandler(const LLSD& payload)
// The channel gets all persistent notifications except those that have been canceled
static bool notificationFilter(LLNotificationPtr pNotification)
{
// we ignore "load" messages, but rewrite the persistence file on any other
std::string sigtype = payload["sigtype"];
if (sigtype != "load")
{
savePersistentNotifications();
}
return false;
bool handle_notification = false;
handle_notification = pNotification->isPersistent()
&& !pNotification->isCancelled();
return handle_notification;
}
// The history channel gets all notifications except those that have been cancelled
static bool historyFilter(LLNotificationPtr pNotification)
{
return !pNotification->isCancelled();
}
void savePersistentNotifications()
{
/* NOTE: As of 2009-11-09 the reload of notifications on startup does not
work, and has not worked for months. Skip saving notifications until the
read can be fixed, because this hits the disk once per notification and
causes log spam. James
llinfos << "Saving open notifications to " << mFileName << llendl;
llofstream notify_file(mFileName.c_str());
if (!notify_file.is_open())
{
llwarns << "Failed to open " << mFileName << llendl;
return;
}
LLSD output;
output["version"] = NOTIFICATION_PERSIST_VERSION;
LLSD& data = output["data"];
for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
{
if (!LLNotifications::instance().templateExists((*it)->getName())) continue;
// only store notifications flagged as persisting
LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate((*it)->getName());
if (!templatep->mPersist) continue;
data.append((*it)->asLLSD());
}
LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY);
*/
}
void loadPersistentNotifications()
{
llinfos << "Loading open notifications from " << mFileName << llendl;
llifstream notify_file(mFileName.c_str());
if (!notify_file.is_open())
{
llwarns << "Failed to open " << mFileName << llendl;
return;
}
LLSD input;
LLPointer<LLSDParser> parser = new LLSDXMLParser();
if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
{
llwarns << "Failed to parse open notifications" << llendl;
return;
}
if (input.isUndefined()) return;
std::string version = input["version"];
if (version != NOTIFICATION_PERSIST_VERSION)
{
llwarns << "Bad open notifications version: " << version << llendl;
return;
}
LLSD& data = input["data"];
if (data.isUndefined()) return;
LLNotifications& instance = LLNotifications::instance();
for (LLSD::array_const_iterator notification_it = data.beginArray();
notification_it != data.endArray();
++notification_it)
{
instance.add(LLNotificationPtr(new LLNotification(*notification_it)));
}
}
//virtual
void onDelete(LLNotificationPtr pNotification)
{
// we want to keep deleted notifications in our log
// we want to keep deleted notifications in our log, otherwise some
// notifications will be lost on exit.
mItems.insert(pNotification);
return;
}
private:
std::string mFileName;
};
bool filterIgnoredNotifications(LLNotificationPtr notification)
@ -417,6 +333,10 @@ LLNotification::LLNotification(const LLNotification::Params& p) :
mTemporaryResponder = true;
}
else if(p.functor.responder.isChosen())
{
mResponder = p.functor.responder;
}
if(p.responder.isProvided())
{
@ -462,6 +382,12 @@ LLSD LLNotification::asLLSD()
output["priority"] = (S32)mPriority;
output["responseFunctor"] = mResponseFunctorName;
output["reusable"] = mIsReusable;
if(mResponder)
{
output["responder"] = mResponder->asLLSD();
}
return output;
}
@ -571,12 +497,20 @@ void LLNotification::respond(const LLSD& response)
// *TODO may remove mRespondedTo and use mResponce.isDefined() in isRespondedTo()
mRespondedTo = true;
mResponse = response;
// look up the functor
LLNotificationFunctorRegistry::ResponseFunctor functor =
LLNotificationFunctorRegistry::instance().getFunctor(mResponseFunctorName);
// and then call it
functor(asLLSD(), response);
if(mResponder)
{
mResponder->handleRespond(asLLSD(), response);
}
else
{
// look up the functor
LLNotificationFunctorRegistry::ResponseFunctor functor =
LLNotificationFunctorRegistry::instance().getFunctor(mResponseFunctorName);
// and then call it
functor(asLLSD(), response);
}
if (mTemporaryResponder && !isReusable())
{
LLNotificationFunctorRegistry::instance().unregisterFunctor(mResponseFunctorName);
@ -621,6 +555,11 @@ void LLNotification::setResponseFunctor(const LLNotificationFunctorRegistry::Res
LLNotificationFunctorRegistry::instance().registerFunctor(mResponseFunctorName, cb);
}
void LLNotification::setResponseFunctor(const LLNotificationResponderPtr& responder)
{
mResponder = responder;
}
bool LLNotification::payloadContainsAll(const std::vector<std::string>& required_fields) const
{
for(std::vector<std::string>::const_iterator required_fields_it = required_fields.begin();
@ -1116,12 +1055,9 @@ void LLNotifications::createDefaultChannels()
LLNotificationChannel::buildChannel("Visible", "Ignore",
&LLNotificationFilters::includeEverything);
// create special history channel
//std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
// use ^^^ when done debugging notifications serialization
std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_USER_SETTINGS, "open_notifications.xml" );
// create special persistent notification channel
// this isn't a leak, don't worry about the empty "new"
new LLNotificationHistoryChannel(notifications_log_file);
new LLPersistentNotificationChannel();
// connect action methods to these channels
LLNotifications::instance().getChannel("Expiration")->

View File

@ -116,8 +116,23 @@ typedef enum e_notification_priority
NOTIFICATION_PRIORITY_CRITICAL
} ENotificationPriority;
class LLNotificationResponderInterface
{
public:
LLNotificationResponderInterface(){};
virtual ~LLNotificationResponderInterface(){};
virtual void handleRespond(const LLSD& notification, const LLSD& response) = 0;
virtual LLSD asLLSD() = 0;
virtual void fromLLSD(const LLSD& params) = 0;
};
typedef boost::function<void (const LLSD&, const LLSD&)> LLNotificationResponder;
typedef boost::shared_ptr<LLNotificationResponderInterface> LLNotificationResponderPtr;
typedef LLFunctorRegistry<LLNotificationResponder> LLNotificationFunctorRegistry;
typedef LLFunctorRegistration<LLNotificationResponder> LLNotificationFunctorRegistration;
@ -303,10 +318,12 @@ public:
{
Alternative<std::string> name;
Alternative<LLNotificationFunctorRegistry::ResponseFunctor> function;
Alternative<LLNotificationResponderPtr> responder;
Functor()
: name("functor_name"),
function("functor")
function("functor"),
responder("responder")
{}
};
Optional<Functor> functor;
@ -349,12 +366,13 @@ private:
bool mIgnored;
ENotificationPriority mPriority;
LLNotificationFormPtr mForm;
void* mResponderObj;
void* mResponderObj; // TODO - refactor/remove this field
bool mIsReusable;
LLNotificationResponderPtr mResponder;
// a reference to the template
LLNotificationTemplatePtr mTemplatep;
/*
We want to be able to store and reload notifications so that they can survive
a shutdown/restart of the client. So we can't simply pass in callbacks;
@ -393,6 +411,8 @@ public:
void setResponseFunctor(const LLNotificationFunctorRegistry::ResponseFunctor& cb);
void setResponseFunctor(const LLNotificationResponderPtr& responder);
typedef enum e_response_template_type
{
WITHOUT_DEFAULT_BUTTON,
@ -459,7 +479,12 @@ public:
{
return mTemplatep->mName;
}
bool isPersistent() const
{
return mTemplatep->mPersist;
}
const LLUUID& id() const
{
return mId;

View File

@ -282,6 +282,8 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
text_p.border_visible(false);
text_p.rect(mItemListRect);
text_p.follows.flags(FOLLOWS_ALL);
// word wrap was added accroding to the EXT-6841
text_p.wrap(true);
addChild(LLUICtrlFactory::create<LLTextBox>(text_p));
}

View File

@ -1507,6 +1507,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
registrar.add("Url.OpenExternal", boost::bind(&LLUrlAction::openURLExternal, url));
registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url));
registrar.add("Url.Teleport", boost::bind(&LLUrlAction::teleportToLocation, url));
registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));

View File

@ -146,3 +146,20 @@ void LLUrlAction::copyLabelToClipboard(std::string url)
LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(match.getLabel()));
}
}
void LLUrlAction::showProfile(std::string url)
{
// Get id from 'secondlife:///app/{cmd}/{id}/{action}'
// and show its profile
LLURI uri(url);
LLSD path_array = uri.pathArray();
if (path_array.size() == 4)
{
std::string id_str = path_array.get(2).asString();
if (LLUUID::validate(id_str))
{
std::string cmd_str = path_array.get(1).asString();
executeSLURL("secondlife:///app/" + cmd_str + "/" + id_str + "/about");
}
}
}

View File

@ -79,6 +79,9 @@ public:
/// copy a Url to the clipboard
static void copyURLToClipboard(std::string url);
/// if the Url specifies an SL command in the form like 'app/{cmd}/{id}/*', show its profile
static void showProfile(std::string url);
/// specify the callbacks to enable this class's functionality
static void setOpenURLCallback(void (*cb) (const std::string& url));
static void setOpenURLInternalCallback(void (*cb) (const std::string& url));

View File

@ -143,6 +143,7 @@ set(viewer_SOURCE_FILES
llfavoritesbar.cpp
llfeaturemanager.cpp
llfilepicker.cpp
llfilteredwearablelist.cpp
llfirstuse.cpp
llflexibleobject.cpp
llfloaterabout.cpp
@ -253,6 +254,7 @@ set(viewer_SOURCE_FILES
llinventoryclipboard.cpp
llinventoryfilter.cpp
llinventoryfunctions.cpp
llinventoryitemslist.cpp
llinventorymodel.cpp
llinventorymodelbackgroundfetch.cpp
llinventoryobserver.cpp
@ -295,7 +297,9 @@ set(viewer_SOURCE_FILES
llnotificationmanager.cpp
llnotificationofferhandler.cpp
llnotificationscripthandler.cpp
llnotificationstorage.cpp
llnotificationtiphandler.cpp
lloutfitslist.cpp
lloutputmonitorctrl.cpp
llpanelavatar.cpp
llpanelavatartag.cpp
@ -328,6 +332,7 @@ set(viewer_SOURCE_FILES
llpanelnearbymedia.cpp
llpanelobject.cpp
llpanelobjectinventory.cpp
llpanelonlinestatus.cpp
llpaneloutfitedit.cpp
llpaneloutfitsinventory.cpp
llpanelpeople.cpp
@ -531,6 +536,7 @@ set(viewer_SOURCE_FILES
llwaterparamset.cpp
llwearable.cpp
llwearabledictionary.cpp
llwearableitemslist.cpp
llwearablelist.cpp
llweb.cpp
llwind.cpp
@ -650,6 +656,7 @@ set(viewer_HEADER_FILES
llfavoritesbar.h
llfeaturemanager.h
llfilepicker.h
llfilteredwearablelist.h
llfirstuse.h
llflexibleobject.h
llfloaterabout.h
@ -759,6 +766,7 @@ set(viewer_HEADER_FILES
llinventoryclipboard.h
llinventoryfilter.h
llinventoryfunctions.h
llinventoryitemslist.h
llinventorymodel.h
llinventorymodelbackgroundfetch.h
llinventoryobserver.h
@ -798,6 +806,8 @@ set(viewer_HEADER_FILES
llnetmap.h
llnotificationhandler.h
llnotificationmanager.h
llnotificationstorage.h
lloutfitslist.h
lloutputmonitorctrl.h
llpanelavatar.h
llpanelavatartag.h
@ -830,6 +840,7 @@ set(viewer_HEADER_FILES
llpanelnearbymedia.h
llpanelobject.h
llpanelobjectinventory.h
llpanelonlinestatus.h
llpaneloutfitedit.h
llpaneloutfitsinventory.h
llpanelpeople.h
@ -1035,6 +1046,7 @@ set(viewer_HEADER_FILES
llwaterparamset.h
llwearable.h
llwearabledictionary.h
llwearableitemslist.h
llwearablelist.h
llweb.h
llwind.h

View File

@ -1338,7 +1338,8 @@ public:
LLSideTray::getInstance()->showPanel("panel_outfits_inventory", key);
LLPanelOutfitsInventory *outfit_panel =
dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
if (outfit_panel)
// TODO: add handling "My Outfits" tab.
if (outfit_panel && outfit_panel->isCOFPanelActive())
{
outfit_panel->getRootFolder()->clearSelection();
outfit_panel->getRootFolder()->setSelectionByID(mFolderID, TRUE);
@ -1361,24 +1362,6 @@ private:
LLUUID mFolderID;
};
LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name)
{
if (!isAgentAvatarValid()) return LLUUID::null;
// First, make a folder in the My Outfits directory.
const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
LLUUID folder_id = gInventory.createNewCategory(
parent_id,
LLFolderType::FT_OUTFIT,
new_folder_name);
LLPointer<LLInventoryCallback> cb = new LLShowCreatedOutfit(folder_id);
LLAppearanceMgr::instance().shallowCopyCategoryContents(LLAppearanceMgr::instance().getCOF(),folder_id, cb);
LLAppearanceMgr::instance().createBaseOutfitLink(folder_id, cb);
return folder_id;
}
void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)
{
LLUUID first_item_id = getWearableItemID((EWearableType)type, index);

View File

@ -169,8 +169,7 @@ public:
const LLDynamicArray<S32>& wearables_to_include,
const LLDynamicArray<S32>& attachments_to_include,
BOOL rename_clothing);
LLUUID makeNewOutfitLinks(const std::string& new_folder_name);
// 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.

View File

@ -119,6 +119,7 @@ public:
item->getLinkedUUID(),
LLAppearanceMgr::instance().getCOF(),
item->getName(),
item->getDescription(),
LLAssetType::AT_LINK,
link_waiter);
}
@ -507,6 +508,7 @@ void LLLibraryOutfitsFetch::contentsDone()
item->getLinkedUUID(),
new_outfit_folder_id,
item->getName(),
item->getDescription(),
LLAssetType::AT_LINK,
NULL);
}

View File

@ -32,6 +32,7 @@
#include "llviewerprecompiledheaders.h"
#include "llaccordionctrltab.h"
#include "llagent.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
@ -42,6 +43,7 @@
#include "llinventoryfunctions.h"
#include "llinventoryobserver.h"
#include "llnotificationsutil.h"
#include "llpaneloutfitsinventory.h"
#include "llselectmgr.h"
#include "llsidepanelappearance.h"
#include "llsidetray.h"
@ -51,6 +53,8 @@
#include "llviewerregion.h"
#include "llwearablelist.h"
char ORDER_NUMBER_SEPARATOR('@');
LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id, const std::string& name)
{
LLInventoryModel::cat_array_t cat_array;
@ -400,6 +404,7 @@ public:
item_id,
LLAppearanceMgr::instance().getCOF(),
itemp->getName(),
itemp->getDescription(),
LLAssetType::AT_LINK,
cb);
}
@ -691,10 +696,13 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
{
case LLAssetType::AT_LINK:
{
//LLInventoryItem::getDescription() is used for a new description
//to propagate ordering information saved in descriptions of links
link_inventory_item(gAgent.getID(),
item->getLinkedUUID(),
dst_id,
item->getName(),
item->LLInventoryItem::getDescription(),
LLAssetType::AT_LINK, cb);
break;
}
@ -708,6 +716,7 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
item->getLinkedUUID(),
dst_id,
item->getName(),
item->getDescription(),
LLAssetType::AT_LINK_FOLDER, cb);
}
break;
@ -811,20 +820,7 @@ void LLAppearanceMgr::filterWearableItems(
{
// Divvy items into arrays by wearable type.
std::vector<LLInventoryModel::item_array_t> items_by_type(WT_COUNT);
for (S32 i=0; i<items.count(); i++)
{
LLViewerInventoryItem *item = items.get(i);
// Ignore non-wearables.
if (!item->isWearableType())
continue;
EWearableType type = item->getWearableType();
if(type < 0 || type >= WT_COUNT)
{
LL_WARNS("Appearance") << "Invalid wearable type. Inventory type does not match wearable flag bitfield." << LL_ENDL;
continue;
}
items_by_type[type].push_back(item);
}
divvyWearablesByType(items, items_by_type);
// rebuild items list, retaining the last max_per_type of each array
items.clear();
@ -853,6 +849,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& category,
item->getLinkedUUID(),
category,
item->getName(),
item->LLInventoryItem::getDescription(),
LLAssetType::AT_LINK,
cb);
}
@ -956,7 +953,7 @@ void LLAppearanceMgr::createBaseOutfitLink(const LLUUID& category, LLPointer<LLI
if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
{
link_inventory_item(gAgent.getID(), category, cof, catp->getName(),
link_inventory_item(gAgent.getID(), category, cof, catp->getName(), "",
LLAssetType::AT_LINK_FOLDER, link_waiter);
new_outfit_name = catp->getName();
}
@ -1016,6 +1013,18 @@ static void remove_non_link_items(LLInventoryModel::item_array_t &items)
items = pruned_items;
}
//a predicate for sorting inventory items by actual descriptions
bool sort_by_description(const LLInventoryItem* item1, const LLInventoryItem* item2)
{
if (!item1 || !item2)
{
llwarning("either item1 or item2 is NULL", 0);
return true;
}
return item1->LLInventoryItem::getDescription() < item2->LLInventoryItem::getDescription();
}
void LLAppearanceMgr::updateAppearanceFromCOF()
{
// update dirty flag to see if the state of the COF matches
@ -1026,6 +1035,8 @@ void LLAppearanceMgr::updateAppearanceFromCOF()
dumpCat(getCOF(),"COF, start");
updateClothingOrderingInfo();
bool follow_folder_links = true;
LLUUID current_outfit_id = getCOF();
@ -1046,6 +1057,9 @@ void LLAppearanceMgr::updateAppearanceFromCOF()
return;
}
//preparing the list of wearables in the correct order for LLAgentWearables
std::sort(wear_items.begin(), wear_items.end(), sort_by_description);
LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
holder->mObjItems = obj_items;
@ -1079,8 +1093,8 @@ void LLAppearanceMgr::updateAppearanceFromCOF()
}
#endif
holder->mFoundList.push_front(found);
//pushing back, not front, to preserve order of wearables for LLAgentWearables
holder->mFoundList.push_back(found);
}
else
{
@ -1407,7 +1421,7 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update
// Are these links to different items of the same wearable
// type? If so, new item will replace old.
// MULTI-WEARABLES: revisit if more than one per type is allowed.
else if (areMatchingWearables(vitem,inv_item))
else if (FALSE/*areMatchingWearables(vitem,inv_item)*/)
{
if (inv_item->getIsLinkType())
{
@ -1430,6 +1444,7 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update
vitem->getLinkedUUID(),
getCOF(),
vitem->getName(),
vitem->getDescription(),
LLAssetType::AT_LINK,
cb);
}
@ -1446,6 +1461,7 @@ void LLAppearanceMgr::addEnsembleLink( LLInventoryCategory* cat, bool do_update
cat->getLinkedUUID(),
getCOF(),
cat->getName(),
cat->getDescription(),
LLAssetType::AT_LINK_FOLDER,
cb);
#endif
@ -1572,6 +1588,8 @@ bool LLAppearanceMgr::updateBaseOutfit()
const LLUUID base_outfit_id = getBaseOutfitUUID();
if (base_outfit_id.isNull()) return false;
updateClothingOrderingInfo();
// in a Base Outfit we do not remove items, only links
purgeCategory(base_outfit_id, false);
@ -1581,6 +1599,168 @@ bool LLAppearanceMgr::updateBaseOutfit()
return true;
}
void LLAppearanceMgr::divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type)
{
items_by_type.reserve(WT_COUNT);
if (items.empty()) return;
for (S32 i=0; i<items.count(); i++)
{
LLViewerInventoryItem *item = items.get(i);
// Ignore non-wearables.
if (!item->isWearableType())
continue;
EWearableType type = item->getWearableType();
if(type < 0 || type >= WT_COUNT)
{
LL_WARNS("Appearance") << "Invalid wearable type. Inventory type does not match wearable flag bitfield." << LL_ENDL;
continue;
}
items_by_type[type].push_back(item);
}
}
std::string build_order_string(EWearableType type, U32 i)
{
std::ostringstream order_num;
order_num << ORDER_NUMBER_SEPARATOR << type * 100 + i;
return order_num.str();
}
struct WearablesOrderComparator
{
WearablesOrderComparator(const EWearableType type)
{
mControlSize = build_order_string(type, 0).size();
};
bool operator()(const LLInventoryItem* item1, const LLInventoryItem* item2)
{
if (!item1 || !item2)
{
llwarning("either item1 or item2 is NULL", 0);
return true;
}
const std::string& desc1 = item1->LLInventoryItem::getDescription();
const std::string& desc2 = item2->LLInventoryItem::getDescription();
bool item1_valid = (desc1.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc1[0]);
bool item2_valid = (desc2.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc2[0]);
if (item1_valid && item2_valid)
return desc1 < desc2;
//we need to sink down invalid items: items with empty descriptions, items with "Broken link" descriptions,
//items with ordering information but not for the associated wearables type
if (!item1_valid && item2_valid)
return false;
return true;
}
U32 mControlSize;
};
void LLAppearanceMgr::updateClothingOrderingInfo()
{
LLInventoryModel::item_array_t wear_items;
getDescendentsOfAssetType(getCOF(), wear_items, LLAssetType::AT_CLOTHING, false);
wearables_by_type_t items_by_type(WT_COUNT);
divvyWearablesByType(wear_items, items_by_type);
bool inventory_changed = false;
for (U32 type = WT_SHIRT; type < WT_COUNT; type++)
{
U32 size = items_by_type[type].size();
if (!size) continue;
//sinking down invalid items which need reordering
std::sort(items_by_type[type].begin(), items_by_type[type].end(), WearablesOrderComparator((EWearableType) type));
//requesting updates only for those links which don't have "valid" descriptions
for (U32 i = 0; i < size; i++)
{
LLViewerInventoryItem* item = items_by_type[type][i];
if (!item) continue;
std::string new_order_str = build_order_string((EWearableType)type, i);
if (new_order_str == item->LLInventoryItem::getDescription()) continue;
item->setDescription(new_order_str);
item->setComplete(TRUE);
item->updateServer(FALSE);
gInventory.updateItem(item);
inventory_changed = true;
}
}
//*TODO do we really need to notify observers?
if (inventory_changed) gInventory.notifyObservers();
}
class LLShowCreatedOutfit: public LLInventoryCallback
{
public:
LLShowCreatedOutfit(LLUUID& folder_id): mFolderID(folder_id)
{}
virtual ~LLShowCreatedOutfit()
{
LLSD key;
LLSideTray::getInstance()->showPanel("panel_outfits_inventory", key);
LLPanelOutfitsInventory *outfit_panel =
dynamic_cast<LLPanelOutfitsInventory*>(LLSideTray::getInstance()->getPanel("panel_outfits_inventory"));
if (outfit_panel)
{
outfit_panel->getRootFolder()->clearSelection();
outfit_panel->getRootFolder()->setSelectionByID(mFolderID, TRUE);
}
LLAccordionCtrlTab* tab_outfits = outfit_panel ? outfit_panel->findChild<LLAccordionCtrlTab>("tab_outfits") : 0;
if (tab_outfits && !tab_outfits->getDisplayChildren())
{
tab_outfits->changeOpenClose(tab_outfits->getDisplayChildren());
}
LLAppearanceMgr::getInstance()->updateIsDirty();
LLAppearanceMgr::getInstance()->updatePanelOutfitName("");
}
virtual void fire(const LLUUID&)
{}
private:
LLUUID mFolderID;
};
LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name)
{
if (!isAgentAvatarValid()) return LLUUID::null;
// First, make a folder in the My Outfits directory.
const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
LLUUID folder_id = gInventory.createNewCategory(
parent_id,
LLFolderType::FT_OUTFIT,
new_folder_name);
updateClothingOrderingInfo();
LLPointer<LLInventoryCallback> cb = new LLShowCreatedOutfit(folder_id);
shallowCopyCategoryContents(getCOF(),folder_id, cb);
createBaseOutfitLink(folder_id, cb);
dumpCat(folder_id,"COF, new outfit");
return folder_id;
}
void LLAppearanceMgr::wearBaseOutfit()
{
const LLUUID& base_outfit_id = getBaseOutfitUUID();

View File

@ -138,12 +138,23 @@ public:
//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);
protected:
LLAppearanceMgr();
~LLAppearanceMgr();
private:
typedef std::vector<LLInventoryModel::item_array_t> wearables_by_type_t;
//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
void updateClothingOrderingInfo();
void filterWearableItems(LLInventoryModel::item_array_t& items, S32 max_per_type);
void getDescendentsOfAssetType(const LLUUID& category,

View File

@ -35,6 +35,7 @@
#include "llchannelmanager.h"
#include "llappviewer.h"
#include "llnotificationstorage.h"
#include "llviewercontrol.h"
#include "llviewerwindow.h"
#include "llrootview.h"
@ -107,31 +108,35 @@ void LLChannelManager::onLoginCompleted()
if(!away_notifications)
{
onStartUpToastClose();
return;
}
// create a channel for the StartUp Toast
LLChannelManager::Params p;
p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
p.channel_align = CA_RIGHT;
mStartUpChannel = createChannel(p);
if(!mStartUpChannel)
else
{
onStartUpToastClose();
return;
// create a channel for the StartUp Toast
LLChannelManager::Params p;
p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
p.channel_align = CA_RIGHT;
mStartUpChannel = createChannel(p);
if(!mStartUpChannel)
{
onStartUpToastClose();
}
else
{
gViewerWindow->getRootView()->addChild(mStartUpChannel);
// init channel's position and size
S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
mStartUpChannel->setMouseDownCallback(boost::bind(&LLNotificationWellWindow::onStartUpToastClick, LLNotificationWellWindow::getInstance(), _2, _3, _4));
mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime"));
}
}
gViewerWindow->getRootView()->addChild(mStartUpChannel);
// init channel's position and size
S32 channel_right_bound = gViewerWindow->getWorldViewRectScaled().mRight - gSavedSettings.getS32("NotificationChannelRightMargin");
S32 channel_width = gSavedSettings.getS32("NotifyBoxWidth");
mStartUpChannel->init(channel_right_bound - channel_width, channel_right_bound);
mStartUpChannel->setMouseDownCallback(boost::bind(&LLNotificationWellWindow::onStartUpToastClick, LLNotificationWellWindow::getInstance(), _2, _3, _4));
mStartUpChannel->setCommitCallback(boost::bind(&LLChannelManager::onStartUpToastClose, this));
mStartUpChannel->createStartUpToast(away_notifications, gSavedSettings.getS32("StartUpToastLifeTime"));
LLPersistentNotificationStorage::getInstance()->loadNotifications();
}
//--------------------------------------------------------------------------

View File

@ -44,6 +44,8 @@
#include "llviewercontrol.h"
#include "llagentdata.h"
#include "llslurl.h"
static const S32 msg_left_offset = 10;
static const S32 msg_right_offset = 10;
static const S32 msg_height_pad = 5;
@ -190,6 +192,8 @@ void LLNearbyChatToastPanel::init(LLSD& notification)
style_params_name.font.name(font_name);
style_params_name.font.size(font_style_size);
style_params_name.link_href = LLSLURL("agent",mFromID,"about").getSLURLString();
msg_text->appendText(str_sender, FALSE, style_params_name);
}

View File

@ -0,0 +1,113 @@
/**
* @file llfilteredwearablelist.cpp
* @brief Functionality for showing filtered wearable flat list
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llfilteredwearablelist.h"
// newview
#include "llinventoryfunctions.h"
#include "llinventoryitemslist.h"
#include "llinventorymodel.h"
class LLFindItemsByMask : public LLInventoryCollectFunctor
{
public:
LLFindItemsByMask(U64 mask)
: mFilterMask(mask)
{}
virtual bool operator()(LLInventoryCategory* cat, LLInventoryItem* item)
{
if(item)
{
if( mFilterMask & (1LL << item->getInventoryType()) )
{
return TRUE;
}
}
return FALSE;
}
private:
U64 mFilterMask;
};
//////////////////////////////////////////////////////////////////////////
LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, U64 filter_mask)
: mWearableList(list)
, mFilterMask(filter_mask)
{
llassert(mWearableList);
gInventory.addObserver(this);
gInventory.fetchDescendentsOf(gInventory.getRootFolderID());
}
LLFilteredWearableListManager::~LLFilteredWearableListManager()
{
gInventory.removeObserver(this);
}
void LLFilteredWearableListManager::changed(U32 mask)
{
if(!gInventory.isInventoryUsable())
{
return;
}
populateList();
}
void LLFilteredWearableListManager::setFilterMask(U64 mask)
{
mFilterMask = mask;
populateList();
}
void LLFilteredWearableListManager::populateList()
{
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
LLFindItemsByMask collector(mFilterMask);
gInventory.collectDescendentsIf(
gInventory.getRootFolderID(),
cat_array,
item_array,
LLInventoryModel::EXCLUDE_TRASH,
collector);
// Probably will also need to get items from Library (waiting for reply in EXT-6724).
mWearableList->refreshList(item_array);
}
// EOF

View File

@ -0,0 +1,70 @@
/**
* @file llfilteredwearablelist.h
* @brief Functionality for showing filtered wearable flat list
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLFILTEREDWEARABLELIST_H
#define LL_LLFILTEREDWEARABLELIST_H
#include "llinventoryobserver.h"
class LLInventoryItemsList;
// Class that fills LLInventoryItemsList with filtered data.
class LLFilteredWearableListManager : public LLInventoryObserver
{
LOG_CLASS(LLFilteredWearableListManager);
public:
LLFilteredWearableListManager(LLInventoryItemsList* list, U64 filter_mask);
~LLFilteredWearableListManager();
/** LLInventoryObserver implementation
*
*/
/*virtual*/ void changed(U32 mask);
/**
* Sets new filter and applies it immediately
*/
void setFilterMask(U64 mask);
/**
* Populates wearable list with filtered data.
*/
void populateList();
private:
LLInventoryItemsList* mWearableList;
U64 mFilterMask;
};
#endif //LL_LLFILTEREDWEARABLELIST_H
// EOF

View File

@ -2520,6 +2520,7 @@ void LLFolderBridge::pasteLinkFromClipboard()
item->getLinkedUUID(),
parent_id,
item->getName(),
item->getDescription(),
LLAssetType::AT_LINK,
LLPointer<LLInventoryCallback>(NULL));
}
@ -3166,6 +3167,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
inv_item->getLinkedUUID(),
mUUID,
inv_item->getName(),
inv_item->getDescription(),
LLAssetType::AT_LINK,
cb);
}

View File

@ -0,0 +1,211 @@
/**
* @file llinventoryitemslist.cpp
* @brief A list of inventory items represented by LLFlatListView.
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llinventoryitemslist.h"
// llcommon
#include "llcommonutils.h"
#include "lliconctrl.h"
#include "llinventoryfunctions.h"
#include "lltextutil.h"
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
LLPanelInventoryItem::LLPanelInventoryItem(LLAssetType::EType asset_type,
LLInventoryType::EType inventory_type,
U32 wearable_type,
const std::string &item_name,
const std::string &hl)
: LLPanel()
,mItemName(item_name)
,mHighlightedText(hl)
,mIcon(NULL)
,mTitle(NULL)
{
mItemIcon = get_item_icon(asset_type, inventory_type, wearable_type, FALSE);
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_inventory_item.xml");
}
LLPanelInventoryItem::~LLPanelInventoryItem()
{}
//virtual
BOOL LLPanelInventoryItem::postBuild()
{
mIcon = getChild<LLIconCtrl>("item_icon");
mTitle = getChild<LLTextBox>("item_name");
updateItem();
return TRUE;
}
//virtual
void LLPanelInventoryItem::setValue(const LLSD& value)
{
if (!value.isMap()) return;
if (!value.has("selected")) return;
childSetVisible("selected_icon", value["selected"]);
}
void LLPanelInventoryItem::updateItem()
{
if (mItemIcon.notNull())
mIcon->setImage(mItemIcon);
LLTextUtil::textboxSetHighlightedVal(
mTitle,
LLStyle::Params(),
mItemName,
mHighlightedText);
}
void LLPanelInventoryItem::onMouseEnter(S32 x, S32 y, MASK mask)
{
childSetVisible("hovered_icon", true);
LLPanel::onMouseEnter(x, y, mask);
}
void LLPanelInventoryItem::onMouseLeave(S32 x, S32 y, MASK mask)
{
childSetVisible("hovered_icon", false);
LLPanel::onMouseLeave(x, y, mask);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
LLInventoryItemsList::LLInventoryItemsList(const LLFlatListView::Params& p)
: LLFlatListView(p)
, mNeedsRefresh(false)
{}
// virtual
LLInventoryItemsList::~LLInventoryItemsList()
{}
void LLInventoryItemsList::refreshList(const LLInventoryModel::item_array_t item_array)
{
getIDs().clear();
LLInventoryModel::item_array_t::const_iterator it = item_array.begin();
for( ; item_array.end() != it; ++it)
{
getIDs().push_back((*it)->getUUID());
}
mNeedsRefresh = true;
}
void LLInventoryItemsList::draw()
{
LLFlatListView::draw();
if(mNeedsRefresh)
{
refresh();
}
}
void LLInventoryItemsList::refresh()
{
static const unsigned ADD_LIMIT = 50;
uuid_vec_t added_items;
uuid_vec_t removed_items;
computeDifference(getIDs(), added_items, removed_items);
bool add_limit_exceeded = false;
unsigned nadded = 0;
uuid_vec_t::const_iterator it = added_items.begin();
for( ; added_items.end() != it; ++it)
{
if(nadded >= ADD_LIMIT)
{
add_limit_exceeded = true;
break;
}
LLViewerInventoryItem* item = gInventory.getItem(*it);
addNewItem(item);
++nadded;
}
it = removed_items.begin();
for( ; removed_items.end() != it; ++it)
{
removeItemByUUID(*it);
}
bool needs_refresh = add_limit_exceeded;
setNeedsRefresh(needs_refresh);
}
void LLInventoryItemsList::computeDifference(
const uuid_vec_t& vnew,
uuid_vec_t& vadded,
uuid_vec_t& vremoved)
{
uuid_vec_t vcur;
{
std::vector<LLSD> vcur_values;
getValues(vcur_values);
for (size_t i=0; i<vcur_values.size(); i++)
vcur.push_back(vcur_values[i].asUUID());
}
LLCommonUtils::computeDifference(vnew, vcur, vadded, vremoved);
}
void LLInventoryItemsList::addNewItem(LLViewerInventoryItem* item)
{
llassert(item);
LLPanelInventoryItem *list_item = new LLPanelInventoryItem(item->getType(),
item->getInventoryType(), item->getFlags(), item->getName(), LLStringUtil::null);
if (!addItem(list_item, item->getUUID()))
{
llwarns << "Couldn't add flat list item." << llendl;
llassert(!"Couldn't add flat list item.");
}
}
// EOF

View File

@ -0,0 +1,122 @@
/**
* @file llinventoryitemslist.h
* @brief A list of inventory items represented by LLFlatListView.
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLINVENTORYITEMSLIST_H
#define LL_LLINVENTORYITEMSLIST_H
#include "llpanel.h"
#include "llassettype.h"
#include "llinventorytype.h"
// newview
#include "llflatlistview.h"
#include "llinventorymodel.h"
class LLIconCtrl;
class LLTextBox;
class LLPanelInventoryItem : public LLPanel
{
public:
LLPanelInventoryItem(LLAssetType::EType asset_type,
LLInventoryType::EType inventory_type,
U32 wearable_type,
const std::string &item_name,
const std::string &hl);
virtual ~LLPanelInventoryItem();
/*virtual*/ BOOL postBuild();
/*virtual*/ void setValue(const LLSD& value);
void updateItem();
void onMouseEnter(S32 x, S32 y, MASK mask);
void onMouseLeave(S32 x, S32 y, MASK mask);
private:
LLIconCtrl* mIcon;
LLTextBox* mTitle;
LLUIImagePtr mItemIcon;
std::string mItemName;
std::string mHighlightedText;
};
class LLInventoryItemsList : public LLFlatListView
{
public:
virtual ~LLInventoryItemsList();
void refreshList(const LLInventoryModel::item_array_t item_array);
/**
* Let list know items need to be refreshed in next draw()
*/
void setNeedsRefresh(bool needs_refresh){ mNeedsRefresh = needs_refresh; }
bool getNeedsRefresh(){ return mNeedsRefresh; }
/*virtual*/ void draw();
protected:
friend class LLUICtrlFactory;
LLInventoryItemsList(const LLFlatListView::Params& p);
uuid_vec_t& getIDs() { return mIDs; }
/**
* Refreshes list items, adds new items and removes deleted items.
* Called from draw() until all new items are added, ,
* maximum 50 items can be added during single call.
*/
void refresh();
/**
* Compute difference between new items and current items, fills 'vadded' with added items,
* 'vremoved' with removed items. See LLCommonUtils::computeDifference
*/
void computeDifference(const uuid_vec_t& vnew, uuid_vec_t& vadded, uuid_vec_t& vremoved);
/**
* Add an item to the list
*/
void addNewItem(LLViewerInventoryItem* item);
private:
uuid_vec_t mIDs; // IDs of items that were added in refreshList().
// Will be used in refresh() to determine added and removed ids
bool mNeedsRefresh;
};
#endif //LL_LLINVENTORYITEMSLIST_H

View File

@ -650,3 +650,35 @@ void LLInventoryTransactionObserver::changed(U32 mask)
}
}
}
void LLInventoryCategoriesObserver::changed(U32 mask)
{
if (!mCategoryMap.size())
return;
for (category_map_t::iterator iter = mCategoryMap.begin();
iter != mCategoryMap.end();
iter++)
{
// Inventory category version is used to find out if some changes
// to a category have been made.
S32 version = gInventory.getCategory((*iter).first)->getVersion();
if (version != (*iter).second.mVersion)
{
// Update category version in map.
(*iter).second.mVersion = version;
(*iter).second.mCallback();
}
}
}
void LLInventoryCategoriesObserver::addCategory(const LLUUID& cat_id, callback_t cb)
{
S32 version = gInventory.getCategory(cat_id)->getVersion();
mCategoryMap.insert(category_map_value_t(cat_id, LLCategoryData(cb, version)));
}
void LLInventoryCategoriesObserver::removeCategory(const LLUUID& cat_id)
{
mCategoryMap.erase(mCategoryMap.find(cat_id));
}

View File

@ -261,5 +261,40 @@ protected:
uuid_vec_t mIncomplete;
};
#endif // LL_LLINVENTORYOBSERVERS_H
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Class LLInventoryCategoriesObserver
//
// This class is used for monitoring a list of inventory categories
// and firing a callback when there are changes in any of them.
// Categories are identified by their UUIDs.
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class LLInventoryCategoriesObserver : public LLInventoryObserver
{
public:
typedef boost::function<void()> callback_t;
LLInventoryCategoriesObserver() {};
virtual void changed(U32 mask);
void addCategory(const LLUUID& cat_id, callback_t cb);
void removeCategory(const LLUUID& cat_id);
protected:
struct LLCategoryData
{
LLCategoryData(callback_t cb, S32 version)
: mCallback(cb)
, mVersion(version)
{}
callback_t mCallback;
S32 mVersion;
};
typedef std::map<LLUUID, LLCategoryData> category_map_t;
typedef category_map_t::value_type category_map_value_t;
category_map_t mCategoryMap;
};
#endif // LL_LLINVENTORYOBSERVERS_H

View File

@ -38,6 +38,7 @@
// common includes
#include "llbutton.h"
#include "llfocusmgr.h"
#include "llhelp.h"
#include "llmenugl.h"
#include "llparcel.h"
#include "llstring.h"
@ -177,6 +178,7 @@ static LLDefaultChildRegistry::Register<LLLocationInputCtrl> r("location_input")
LLLocationInputCtrl::Params::Params()
: icon_maturity_general("icon_maturity_general"),
icon_maturity_adult("icon_maturity_adult"),
icon_maturity_moderate("icon_maturity_moderate"),
add_landmark_image_enabled("add_landmark_image_enabled"),
add_landmark_image_disabled("add_landmark_image_disabled"),
add_landmark_image_hover("add_landmark_image_hover"),
@ -186,14 +188,15 @@ LLLocationInputCtrl::Params::Params()
add_landmark_button("add_landmark_button"),
for_sale_button("for_sale_button"),
info_button("info_button"),
maturity_icon("maturity_icon"),
maturity_button("maturity_button"),
voice_icon("voice_icon"),
fly_icon("fly_icon"),
push_icon("push_icon"),
build_icon("build_icon"),
scripts_icon("scripts_icon"),
damage_icon("damage_icon"),
damage_text("damage_text")
damage_text("damage_text"),
maturity_help_topic("maturity_help_topic")
{
}
@ -208,7 +211,9 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
mLandmarkImageOn(NULL),
mLandmarkImageOff(NULL),
mIconMaturityGeneral(NULL),
mIconMaturityAdult(NULL)
mIconMaturityAdult(NULL),
mIconMaturityModerate(NULL),
mMaturityHelpTopic(p.maturity_help_topic)
{
// Lets replace default LLLineEditor with LLLocationLineEditor
// to make needed escaping while copying and cutting url
@ -276,10 +281,15 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
{
mIconMaturityAdult = p.icon_maturity_adult;
}
if(p.icon_maturity_moderate())
{
mIconMaturityModerate = p.icon_maturity_moderate;
}
LLIconCtrl::Params maturity_icon = p.maturity_icon;
mMaturityIcon = LLUICtrlFactory::create<LLIconCtrl>(maturity_icon);
addChild(mMaturityIcon);
LLButton::Params maturity_button = p.maturity_button;
mMaturityButton = LLUICtrlFactory::create<LLButton>(maturity_button);
addChild(mMaturityButton);
mMaturityButton->setClickedCallback(boost::bind(&LLLocationInputCtrl::onMaturityButtonClicked, this));
LLButton::Params for_sale_button = p.for_sale_button;
for_sale_button.tool_tip = LLTrans::getString("LocationCtrlForSaleTooltip");
@ -576,7 +586,7 @@ void LLLocationInputCtrl::reshape(S32 width, S32 height, BOOL called_from_parent
if (isHumanReadableLocationVisible)
{
refreshMaturityIcon();
refreshMaturityButton();
}
}
@ -613,6 +623,11 @@ void LLLocationInputCtrl::onAgentParcelChange()
refresh();
}
void LLLocationInputCtrl::onMaturityButtonClicked()
{
LLUI::sHelpImpl->showTopic(mMaturityHelpTopic);
}
void LLLocationInputCtrl::onLandmarkLoaded(LLLandmark* lm)
{
(void) lm;
@ -735,7 +750,7 @@ void LLLocationInputCtrl::refreshLocation()
setText(location_name);
isHumanReadableLocationVisible = true;
refreshMaturityIcon();
refreshMaturityButton();
}
// returns new right edge
@ -851,37 +866,54 @@ void LLLocationInputCtrl::refreshHealth()
}
}
void LLLocationInputCtrl::refreshMaturityIcon()
void LLLocationInputCtrl::refreshMaturityButton()
{
// Updating maturity rating icon.
LLViewerRegion* region = gAgent.getRegion();
if (!region)
return;
bool button_visible = true;
LLPointer<LLUIImage> rating_image = NULL;
std::string rating_tooltip;
U8 sim_access = region->getSimAccess();
switch(sim_access)
{
case SIM_ACCESS_PG:
mMaturityIcon->setValue(mIconMaturityGeneral->getName());
mMaturityIcon->setVisible(TRUE);
rating_image = mIconMaturityGeneral;
rating_tooltip = LLTrans::getString("LocationCtrlGeneralIconTooltip");
break;
case SIM_ACCESS_ADULT:
mMaturityIcon->setValue(mIconMaturityAdult->getName());
mMaturityIcon->setVisible(TRUE);
rating_image = mIconMaturityAdult;
rating_tooltip = LLTrans::getString("LocationCtrlAdultIconTooltip");
break;
case SIM_ACCESS_MATURE:
rating_image = mIconMaturityModerate;
rating_tooltip = LLTrans::getString("LocationCtrlModerateIconTooltip");
break;
default:
mMaturityIcon->setVisible(FALSE);
button_visible = false;
break;
}
if (mMaturityIcon->getVisible())
mMaturityButton->setVisible(button_visible);
mMaturityButton->setToolTip(rating_tooltip);
if(rating_image)
{
positionMaturityIcon();
mMaturityButton->setImageUnselected(rating_image);
mMaturityButton->setImagePressed(rating_image);
}
if (mMaturityButton->getVisible())
{
positionMaturityButton();
}
}
void LLLocationInputCtrl::positionMaturityIcon()
void LLLocationInputCtrl::positionMaturityButton()
{
const LLFontGL* font = mTextEntry->getFont();
if (!font)
@ -893,11 +925,11 @@ void LLLocationInputCtrl::positionMaturityIcon()
// Calculate the right edge of rendered text + a whitespace.
left_pad = left_pad + font->getWidth(mTextEntry->getText()) + font->getWidth(" ");
LLRect rect = mMaturityIcon->getRect();
mMaturityIcon->setRect(rect.setOriginAndSize(left_pad, rect.mBottom, rect.getWidth(), rect.getHeight()));
LLRect rect = mMaturityButton->getRect();
mMaturityButton->setRect(rect.setOriginAndSize(left_pad, rect.mBottom, rect.getWidth(), rect.getHeight()));
// Hide icon if it text area is not width enough to display it, show otherwise.
mMaturityIcon->setVisible(rect.mRight < mTextEntry->getRect().getWidth() - right_pad);
mMaturityButton->setVisible(rect.mRight < mTextEntry->getRect().getWidth() - right_pad);
}
void LLLocationInputCtrl::rebuildLocationHistory(const std::string& filter)
@ -1015,7 +1047,7 @@ void LLLocationInputCtrl::changeLocationPresentation()
mTextEntry->setText(slurl.getSLURLString());
mTextEntry->selectAll();
mMaturityIcon->setVisible(FALSE);
mMaturityButton->setVisible(FALSE);
isHumanReadableLocationVisible = false;
}

View File

@ -66,17 +66,19 @@ public:
{
Optional<LLUIImage*> icon_maturity_general,
icon_maturity_adult,
icon_maturity_moderate,
add_landmark_image_enabled,
add_landmark_image_disabled,
add_landmark_image_hover,
add_landmark_image_selected;
Optional<std::string> maturity_help_topic;
Optional<S32> icon_hpad,
add_landmark_hpad;
Optional<LLButton::Params> add_landmark_button,
Optional<LLButton::Params> maturity_button,
add_landmark_button,
for_sale_button,
info_button;
Optional<LLIconCtrl::Params> maturity_icon,
voice_icon,
Optional<LLIconCtrl::Params> voice_icon,
fly_icon,
push_icon,
build_icon,
@ -136,8 +138,8 @@ private:
void refreshParcelIcons();
// Refresh the value in the health percentage text field
void refreshHealth();
void refreshMaturityIcon();
void positionMaturityIcon();
void refreshMaturityButton();
void positionMaturityButton();
void rebuildLocationHistory(const std::string& filter = LLStringUtil::null);
bool findTeleportItemsByTitle(const LLTeleportHistoryItem& item, const std::string& filter);
@ -156,6 +158,7 @@ private:
void onForSaleButtonClicked();
void onAddLandmarkButtonClicked();
void onAgentParcelChange();
void onMaturityButtonClicked();
// callbacks
bool onLocationContextMenuItemEnabled(const LLSD& userdata);
void onLocationContextMenuItemClicked(const LLSD& userdata);
@ -168,7 +171,7 @@ private:
S32 mIconHPad; // pad between all icons
S32 mAddLandmarkHPad; // pad to left of landmark star
LLIconCtrl* mMaturityIcon;
LLButton* mMaturityButton;
LLIconCtrl* mParcelIcon[ICON_COUNT];
LLTextBox* mDamageText;
@ -182,14 +185,16 @@ private:
boost::signals2::connection mLocationHistoryConnection;
LLUIImage* mLandmarkImageOn;
LLUIImage* mLandmarkImageOff;
LLUIImage* mIconMaturityGeneral;
LLUIImage* mIconMaturityAdult;
LLPointer<LLUIImage> mIconMaturityGeneral;
LLPointer<LLUIImage> mIconMaturityAdult;
LLPointer<LLUIImage> mIconMaturityModerate;
std::string mAddLandmarkTooltip;
std::string mEditLandmarkTooltip;
// this field holds a human-readable form of the location string, it is needed to be able to compare copy-pated value and real location
std::string mHumanReadableLocation;
bool isHumanReadableLocationVisible;
std::string mMaturityHelpTopic;
};
#endif

View File

@ -81,7 +81,7 @@ void LLNameListCtrl::addNameItem(const LLUUID& agent_id, EAddPosition pos,
item.enabled = enabled;
item.target = INDIVIDUAL;
addNameItemRow(item, pos);
addNameItemRow(item, pos, suffix);
}
// virtual, public

View File

@ -0,0 +1,228 @@
/**
* @file llnotificationstorage.cpp
* @brief LLPersistentNotificationStorage class implementation
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h" // must be first include
#include "llnotificationstorage.h"
#include "llxmlnode.h" // for linux compilers
#include "llchannelmanager.h"
#include "llscreenchannel.h"
#include "llscriptfloater.h"
#include "llsdserialize.h"
#include "llviewermessage.h"
//////////////////////////////////////////////////////////////////////////
class LLResponderRegistry
{
public:
static void registerResponders();
static LLNotificationResponderInterface* createResponder(const std::string& notification_name, const LLSD& params);
private:
template<typename RESPONDER_TYPE>
static LLNotificationResponderInterface* create(const LLSD& params)
{
RESPONDER_TYPE* responder = new RESPONDER_TYPE();
responder->fromLLSD(params);
return responder;
}
typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t;
static void add(const std::string& notification_name, const responder_constructor_t& ctr);
private:
typedef std::map<std::string, responder_constructor_t> build_map_t;
static build_map_t sBuildMap;
};
//////////////////////////////////////////////////////////////////////////
LLPersistentNotificationStorage::LLPersistentNotificationStorage()
{
mFileName = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
}
bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
{
// we ignore "load" messages, but rewrite the persistence file on any other
const std::string sigtype = payload["sigtype"].asString();
if ("load" != sigtype)
{
saveNotifications();
}
return false;
}
void LLPersistentNotificationStorage::saveNotifications()
{
// TODO - think about save optimization.
llofstream notify_file(mFileName.c_str());
if (!notify_file.is_open())
{
llwarns << "Failed to open " << mFileName << llendl;
return;
}
LLSD output;
LLSD& data = output["data"];
LLNotificationChannelPtr history_channel = LLNotifications::instance().getChannel("Persistent");
LLNotificationSet::iterator it = history_channel->begin();
for ( ; history_channel->end() != it; ++it)
{
LLNotificationPtr notification = *it;
// After a notification was placed in Persist channel, it can become
// responded, expired - in this case we are should not save it
if(notification->isRespondedTo()
|| notification->isExpired())
{
continue;
}
data.append(notification->asLLSD());
}
LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY);
}
void LLPersistentNotificationStorage::loadNotifications()
{
LLResponderRegistry::registerResponders();
LLNotifications::instance().getChannel("Persistent")->
connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
llifstream notify_file(mFileName.c_str());
if (!notify_file.is_open())
{
llwarns << "Failed to open " << mFileName << llendl;
return;
}
LLSD input;
LLPointer<LLSDParser> parser = new LLSDXMLParser();
if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
{
llwarns << "Failed to parse open notifications" << llendl;
return;
}
if (input.isUndefined())
{
return;
}
LLSD& data = input["data"];
if (data.isUndefined())
{
return;
}
using namespace LLNotificationsUI;
LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
LLNotifications& instance = LLNotifications::instance();
for (LLSD::array_const_iterator notification_it = data.beginArray();
notification_it != data.endArray();
++notification_it)
{
LLSD notification_params = *notification_it;
LLNotificationPtr notification(new LLNotification(notification_params));
LLNotificationResponderPtr responder(LLResponderRegistry::
createResponder(notification_params["name"], notification_params["responder"]));
notification->setResponseFunctor(responder);
instance.add(notification);
// hide script floaters so they don't confuse the user and don't overlap startup toast
LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
if(notification_channel)
{
// hide saved toasts so they don't confuse the user
notification_channel->hideToast(notification->getID());
}
}
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
LLResponderRegistry::build_map_t LLResponderRegistry::sBuildMap;
void LLResponderRegistry::registerResponders()
{
sBuildMap.clear();
add("ObjectGiveItem", &create<LLOfferInfo>);
add("UserGiveItem", &create<LLOfferInfo>);
}
LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& notification_name, const LLSD& params)
{
build_map_t::const_iterator it = sBuildMap.find(notification_name);
if(sBuildMap.end() == it)
{
llwarns << "Responder for notification \'" << notification_name << "\' is not registered" << llendl;
return NULL;
}
responder_constructor_t ctr = it->second;
return ctr(params);
}
void LLResponderRegistry::add(const std::string& notification_name, const responder_constructor_t& ctr)
{
if(sBuildMap.find(notification_name) != sBuildMap.end())
{
llwarns << "Responder is already registered : " << notification_name << llendl;
llassert(!"Responder already registered");
}
sBuildMap[notification_name] = ctr;
}
// EOF

View File

@ -0,0 +1,65 @@
/**
* @file llnotificationstorage.h
* @brief LLNotificationStorage class declaration
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_NOTIFICATIONSTORAGE_H
#define LL_NOTIFICATIONSTORAGE_H
#include "llnotifications.h"
// Class that saves not responded(unread) notifications.
// Unread notifications are saved in open_notifications.xml in SL account folder
//
// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml
// Notifications using functor responders are saved automatically (see llviewermessage.cpp
// lure_callback_reg for example).
// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should
// be a) serializable(implement LLNotificationResponderInterface),
// b) registered with LLResponderRegistry (found in llnotificationstorage.cpp).
class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>
{
LOG_CLASS(LLPersistentNotificationStorage);
public:
LLPersistentNotificationStorage();
void saveNotifications();
void loadNotifications();
private:
bool onPersistentChannelChanged(const LLSD& payload);
std::string mFileName;
};
#endif // LL_NOTIFICATIONSTORAGE_H

View File

@ -45,38 +45,6 @@
using namespace LLNotificationsUI;
class LLOnlineStatusToast : public LLPanelTipToast
{
public:
struct Params
{
LLNotificationPtr notification;
LLUUID avatar_id;
std::string message;
Params() {}
};
LLOnlineStatusToast(Params& p) : LLPanelTipToast(p.notification)
{
LLUICtrlFactory::getInstance()->buildPanel(this, "panel_online_status_toast.xml");
childSetValue("avatar_icon", p.avatar_id);
childSetValue("message", p.message);
if (p.notification->getPayload().has("respond_on_mousedown")
&& p.notification->getPayload()["respond_on_mousedown"] )
{
setMouseDownCallback(boost::bind(&LLNotification::respond, p.notification,
p.notification->getResponseTemplate()));
}
// set line max count to 3 in case of a very long name
snapToMessageHeight(getChild<LLTextBox>("message"), 3);
}
};
//--------------------------------------------------------------------------
LLTipHandler::LLTipHandler(e_notification_type type, const LLSD& id)
{
@ -157,28 +125,7 @@ bool LLTipHandler::processNotification(const LLSD& notify)
return true;
}
LLToastPanel* notify_box = NULL;
// TODO: this should be implemented in LLToastPanel::buidPanelFromNotification
if("FriendOffline" == notification->getName() || "FriendOnline" == notification->getName())
{
LLOnlineStatusToast::Params p;
p.notification = notification;
p.message = notification->getMessage();
p.avatar_id = notification->getPayload()["FROM_ID"];
notify_box = new LLOnlineStatusToast(p);
}
else
{
notify_box = LLToastPanel::buidPanelFromNotification(notification);
}
// TODO: this if statement should be removed after modification of
// LLToastPanel::buidPanelFromNotification() to allow create generic tip panel
// for all tip notifications except FriendOnline and FriendOffline
if (notify_box == NULL)
{
notify_box = new LLToastNotifyPanel(notification);
}
LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
LLToast::Params p;
p.notif_id = notification->getID();

View File

@ -0,0 +1,265 @@
/**
* @file lloutfitslist.cpp
* @brief List of agent's outfits for My Appearance side panel.
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "lloutfitslist.h"
#include "llaccordionctrl.h"
#include "llaccordionctrltab.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
#include "llwearableitemslist.h"
static LLRegisterPanelClassWrapper<LLOutfitsList> t_outfits_list("outfits_list");
LLOutfitsList::LLOutfitsList()
: LLPanel()
, mAccordion(NULL)
, mListCommands(NULL)
{}
LLOutfitsList::~LLOutfitsList()
{
if (gInventory.containsObserver(mCategoriesObserver))
{
gInventory.removeObserver(mCategoriesObserver);
delete mCategoriesObserver;
}
if (gInventory.containsObserver(this))
{
gInventory.removeObserver(this);
}
}
BOOL LLOutfitsList::postBuild()
{
mAccordion = getChild<LLAccordionCtrl>("outfits_accordion");
mCategoriesObserver = new LLInventoryCategoriesObserver();
gInventory.addObserver(mCategoriesObserver);
gInventory.addObserver(this);
return TRUE;
}
//virtual
void LLOutfitsList::changed(U32 mask)
{
if (!gInventory.isInventoryUsable())
return;
// Start observing changes in "My Outfits" category.
const LLUUID outfits = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
mCategoriesObserver->addCategory(outfits,
boost::bind(&LLOutfitsList::refreshList, this, outfits));
LLViewerInventoryCategory* category = gInventory.getCategory(outfits);
if (!category)
return;
// Fetch "My Outfits" contents and refresh the list to display
// initially fetched items. If not all items are fetched now
// the observer will refresh the list as soon as the new items
// arrive.
category->fetch();
refreshList(outfits);
// This observer is used to start the initial outfits fetch
// when inventory becomes usable. It is no longer needed because
// "My Outfits" category is now observed by
// LLInventoryCategoriesObserver.
gInventory.removeObserver(this);
}
void LLOutfitsList::refreshList(const LLUUID& category_id)
{
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
// Collect all sub-categories of a given category.
LLIsType is_category(LLAssetType::AT_CATEGORY);
gInventory.collectDescendentsIf(
category_id,
cat_array,
item_array,
LLInventoryModel::EXCLUDE_TRASH,
is_category);
uuid_vec_t vnew;
// Creating a vector of newly collected sub-categories UUIDs.
for (LLInventoryModel::cat_array_t::const_iterator iter = cat_array.begin();
iter != cat_array.end();
iter++)
{
vnew.push_back((*iter)->getUUID());
}
uuid_vec_t vcur;
// Creating a vector of currently displayed sub-categories UUIDs.
for (outfits_map_t::const_iterator iter = mOutfitsMap.begin();
iter != mOutfitsMap.end();
iter++)
{
vcur.push_back((*iter).first);
}
// Sorting both vectors to compare.
std::sort(vcur.begin(), vcur.end());
std::sort(vnew.begin(), vnew.end());
uuid_vec_t vadded;
uuid_vec_t vremoved;
uuid_vec_t::iterator it;
size_t maxsize = llmax(vcur.size(), vnew.size());
vadded.resize(maxsize);
vremoved.resize(maxsize);
// what to remove
it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
vremoved.erase(it, vremoved.end());
// what to add
it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
vadded.erase(it, vadded.end());
// Handle added tabs.
for (uuid_vec_t::const_iterator iter = vadded.begin();
iter != vadded.end();
iter++)
{
const LLUUID cat_id = (*iter);
LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
if (!cat)
continue;
std::string name = cat->getName();
// *TODO: create accordion tabs and lists from XML.
LLAccordionCtrlTab::Params params;
params.name(name);
params.title(name);
params.rect(LLRect(0, 0, 315, 20));
params.display_children(false);
LLAccordionCtrlTab* tab = LLUICtrlFactory::create<LLAccordionCtrlTab>(params);
mAccordion->addCollapsibleCtrl(tab);
LLFlatListView::Params list_params;
LLWearableItemsList* list = LLUICtrlFactory::create<LLWearableItemsList>(list_params);
tab->addChild(list, 0);
tab->setDisplayChildren(false);
// Map the new tab with outfit category UUID.
mOutfitsMap.insert(LLOutfitsList::outfits_map_value_t(cat_id, tab));
// Start observing the new outfit category.
mCategoriesObserver->addCategory(cat_id, boost::bind(&LLWearableItemsList::updateList, list, cat_id));
// Fetch the new outfit contents.
cat->fetch();
// Refresh the list of outfit items after fetch().
// Further list updates will be triggered by the category observer.
list->updateList(cat_id);
}
// Handle removed tabs.
for (uuid_vec_t::const_iterator iter=vremoved.begin(); iter != vremoved.end(); iter++)
{
outfits_map_t::iterator outfits_iter = mOutfitsMap.find((*iter));
if (outfits_iter != mOutfitsMap.end())
{
// An outfit is removed from the list. Do the following:
// 1. Remove outfit accordion tab from accordion.
mAccordion->removeCollapsibleCtrl(outfits_iter->second);
// 2. Remove outfit category from observer to stop monitoring its changes.
mCategoriesObserver->removeCategory(outfits_iter->first);
// 3. Remove category UUID to accordion tab mapping.
mOutfitsMap.erase(outfits_iter);
}
}
// Get changed items from inventory model and update outfit tabs
// which might have been renamed.
const LLInventoryModel::changed_items_t& changed_items = gInventory.getChangedIDs();
for (LLInventoryModel::changed_items_t::const_iterator items_iter = changed_items.begin();
items_iter != changed_items.end();
++items_iter)
{
updateOutfitTab(*items_iter);
}
mAccordion->arrange();
}
void LLOutfitsList::updateOutfitTab(const LLUUID& category_id)
{
outfits_map_t::iterator outfits_iter = mOutfitsMap.find(category_id);
if (outfits_iter != mOutfitsMap.end())
{
LLViewerInventoryCategory *cat = gInventory.getCategory(category_id);
if (!cat)
return;
std::string name = cat->getName();
// Update tab name with the new category name.
LLAccordionCtrlTab* tab = outfits_iter->second;
if (tab)
{
tab->setName(name);
}
// Update tab title with the new category name using textbox
// in accordion tab header.
LLTextBox* tab_title = tab->findChild<LLTextBox>("dd_textbox");
if (tab_title)
{
tab_title->setText(name);
}
}
}
void LLOutfitsList::setFilterSubString(const std::string& string)
{
mFilterSubString = string;
}
// EOF

View File

@ -0,0 +1,74 @@
/**
* @file lloutfitslist.h
* @brief List of agent's outfits for My Appearance side panel.
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLOUTFITSLIST_H
#define LL_LLOUTFITSLIST_H
#include "llpanel.h"
// newview
#include "llinventoryobserver.h"
class LLAccordionCtrl;
class LLAccordionCtrlTab;
class LLWearableItemsList;
class LLOutfitsList : public LLPanel, public LLInventoryObserver
{
public:
LLOutfitsList();
virtual ~LLOutfitsList();
/*virtual*/ BOOL postBuild();
/*virtual*/ void changed(U32 mask);
void refreshList(const LLUUID& category_id);
// Update tab displaying outfit identified by category_id.
void updateOutfitTab(const LLUUID& category_id);
void setFilterSubString(const std::string& string);
private:
LLInventoryCategoriesObserver* mCategoriesObserver;
LLAccordionCtrl* mAccordion;
LLPanel* mListCommands;
std::string mFilterSubString;
typedef std::map<LLUUID, LLAccordionCtrlTab*> outfits_map_t;
typedef outfits_map_t::value_type outfits_map_value_t;
outfits_map_t mOutfitsMap;
};
#endif //LL_LLOUTFITSLIST_H

View File

@ -37,7 +37,7 @@
#include "lltimer.h"
#include "llvoiceclient.h"
struct LLOfferInfo;
class LLOfferInfo;
const S32 UPDATE_MEMBERS_PER_FRAME = 500;

View File

@ -1075,7 +1075,7 @@ void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
This->mPasswordModified = TRUE;
if (gKeyboard->getKeyDown(KEY_CAPSLOCK) && sCapslockDidNotification == FALSE)
{
LLNotificationsUtil::add("CapsKeyOn");
// *TODO: use another way to notify user about enabled caps lock, see EXT-6858
sCapslockDidNotification = TRUE;
}
}

View File

@ -63,7 +63,6 @@ BOOL LLPanelMe::postBuild()
LLPanelProfile::postBuild();
getTabContainer()[PANEL_PROFILE]->childSetAction("edit_profile_btn", boost::bind(&LLPanelMe::onEditProfileClicked, this), this);
getTabContainer()[PANEL_PROFILE]->childSetAction("edit_appearance_btn", boost::bind(&LLPanelMe::onEditAppearanceClicked, this), this);
return TRUE;
}
@ -141,14 +140,6 @@ void LLPanelMe::onEditProfileClicked()
togglePanel(mEditPanel, getAvatarId()); // open
}
void LLPanelMe::onEditAppearanceClicked()
{
if (gAgentWearables.areWearablesLoaded())
{
gAgentCamera.changeCameraToCustomizeAvatar();
}
}
void LLPanelMe::onSaveChangesClicked()
{
LLAvatarData data = LLAvatarData();

View File

@ -63,7 +63,6 @@ private:
void buildEditPanel();
void onEditProfileClicked();
void onEditAppearanceClicked();
void onSaveChangesClicked();
void onCancelClicked();

View File

@ -0,0 +1,60 @@
/**
* @file llpanelonlinestatus.cpp
* @brief Represents a class of online status tip toast panels.
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llnotifications.h"
#include "llpanelonlinestatus.h"
LLPanelOnlineStatus::LLPanelOnlineStatus(
const LLNotificationPtr& notification) :
LLPanelTipToast(notification)
{
LLUICtrlFactory::getInstance()->buildPanel(this,
"panel_online_status_toast.xml");
childSetValue("avatar_icon", notification->getPayload()["FROM_ID"]);
childSetValue("message", notification->getMessage());
if (notification->getPayload().has("respond_on_mousedown")
&& notification->getPayload()["respond_on_mousedown"])
{
setMouseDownCallback(boost::bind(&LLNotification::respond,
notification, notification->getResponseTemplate()));
}
// set line max count to 3 in case of a very long name
snapToMessageHeight(getChild<LLTextBox> ("message"), 3);
}

View File

@ -0,0 +1,53 @@
/**
* @file llpanelonlinestatus.h
* @brief Represents a class of online status tip toast panels.
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llpaneltiptoast.h"
#ifndef LL_PANELONLINESTATUS_H
#define LL_PANELONLINESTATUS_H
/**
* Represents online tip toast panel.
*/
class LLPanelOnlineStatus : public LLPanelTipToast
{
// disallow instantiation of this class
private:
// grant privileges to instantiate this class to LLToastPanel
friend class LLToastPanel;
LLPanelOnlineStatus(const LLNotificationPtr& notification);
virtual ~LLPanelOnlineStatus() {}
};
#endif /* LL_PANELONLINESTATUS_H */

View File

@ -38,7 +38,9 @@
#include "llagent.h"
#include "llagentwearables.h"
#include "llappearancemgr.h"
#include "llfilteredwearablelist.h"
#include "llinventory.h"
#include "llinventoryitemslist.h"
#include "llviewercontrol.h"
#include "llui.h"
#include "llfloater.h"
@ -164,6 +166,7 @@ BOOL LLPanelOutfitEdit::postBuild()
childSetCommitCallback("add_btn", boost::bind(&LLPanelOutfitEdit::showAddWearablesPanel, this), NULL);
childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL);
childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showFilteredWearablesPanel, this), NULL);
mLookContents = getChild<LLScrollListCtrl>("look_items_list");
mLookContents->sortByColumn("look_item_sort", TRUE);
@ -229,6 +232,9 @@ BOOL LLPanelOutfitEdit::postBuild()
save_registar.add("Outfit.SaveAsNew.Action", boost::bind(&LLPanelOutfitEdit::saveOutfit, this, true));
mSaveMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_save_outfit.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
mWearableListManager = new LLFilteredWearableListManager(
getChild<LLInventoryItemsList>("filtered_wearables_list"), ALL_ITEMS_MASK);
return TRUE;
}
@ -242,6 +248,11 @@ void LLPanelOutfitEdit::showWearablesFilter()
childSetVisible("filter_combobox_panel", childGetValue("filter_button"));
}
void LLPanelOutfitEdit::showFilteredWearablesPanel()
{
childSetVisible("filtered_wearables_panel", !childIsVisible("filtered_wearables_panel"));
}
void LLPanelOutfitEdit::saveOutfit(bool as_new)
{
if (!as_new && LLAppearanceMgr::getInstance()->updateBaseOutfit())
@ -275,6 +286,7 @@ void LLPanelOutfitEdit::onTypeFilterChanged(LLUICtrl* ctrl)
{
U32 curr_filter_type = type_filter->getCurrentIndex();
mInventoryItemsPanel->setFilterTypes(mLookItemTypes[curr_filter_type].inventoryMask);
mWearableListManager->setFilterMask(mLookItemTypes[curr_filter_type].inventoryMask);
}
mSavedFolderState->setApply(TRUE);
@ -577,4 +589,4 @@ void LLPanelOutfitEdit::displayCurrentOutfit()
updateLookInfo();
}
// EOF

View File

@ -55,6 +55,7 @@ class LLScrollListCtrl;
class LLToggleableMenu;
class LLLookFetchObserver;
class LLFilterEditor;
class LLFilteredWearableListManager;
class LLPanelOutfitEdit : public LLPanel
{
@ -88,6 +89,7 @@ public:
void showAddWearablesPanel();
void showWearablesFilter();
void showFilteredWearablesPanel();
void saveOutfit(bool as_new = false);
void showSaveMenu();
@ -122,7 +124,9 @@ private:
LLButton* mUpBtn;
LLButton* mEditWearableBtn;
LLToggleableMenu* mSaveMenu;
LLFilteredWearableListManager* mWearableListManager;
LLLookFetchObserver* mFetchLook;
LLInventoryLookObserver* mLookObserver;
std::vector<LLLookItemType> mLookItemTypes;

View File

@ -49,6 +49,7 @@
#include "lllineeditor.h"
#include "llmodaldialog.h"
#include "llnotificationsutil.h"
#include "lloutfitslist.h"
#include "llsidepanelappearance.h"
#include "llsidetray.h"
#include "lltabcontainer.h"
@ -71,7 +72,8 @@ bool LLPanelOutfitsInventory::sShowDebugEditor = false;
LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
mActivePanel(NULL),
mMyOutfitsPanel(NULL),
mCurrentOutfitPanel(NULL),
mParent(NULL)
{
mSavedFolderState = new LLSaveFolderState();
@ -145,9 +147,17 @@ void LLPanelOutfitsInventory::setParent(LLSidepanelAppearance* parent)
void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
{
mFilterSubString = string;
// TODO: add handling "My Outfits" tab.
if (!isCOFPanelActive())
{
mMyOutfitsPanel->setFilterSubString(string);
return;
}
if (string == "")
{
mActivePanel->setFilterSubString(LLStringUtil::null);
getActivePanel()->setFilterSubString(LLStringUtil::null);
// re-open folders that were initially open
mSavedFolderState->setApply(TRUE);
@ -159,7 +169,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
LLInventoryModelBackgroundFetch::instance().start();
if (mActivePanel->getFilterSubString().empty() && string.empty())
if (getActivePanel()->getFilterSubString().empty() && string.empty())
{
// current filter and new filter empty, do nothing
return;
@ -173,7 +183,7 @@ void LLPanelOutfitsInventory::onSearchEdit(const std::string& string)
}
// set new filter string
mActivePanel->setFilterSubString(string);
getActivePanel()->setFilterSubString(string);
}
void LLPanelOutfitsInventory::onWearButtonClick()
@ -216,7 +226,7 @@ bool LLPanelOutfitsInventory::onSaveCommit(const LLSD& notification, const LLSD&
LLStringUtil::trim(outfit_name);
if( !outfit_name.empty() )
{
LLUUID outfit_folder = gAgentWearables.makeNewOutfitLinks(outfit_name);
LLUUID outfit_folder = LLAppearanceMgr::getInstance()->makeNewOutfitLinks(outfit_name);
LLSidepanelAppearance* panel_appearance =
dynamic_cast<LLSidepanelAppearance *>(LLSideTray::getInstance()->getPanel("sidepanel_appearance"));
@ -267,6 +277,11 @@ void LLPanelOutfitsInventory::onSave()
void LLPanelOutfitsInventory::onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action)
{
updateVerbs();
// TODO: add handling "My Outfits" tab.
if (!isCOFPanelActive())
return;
if (getRootFolder()->needsAutoRename() && items.size())
{
getRootFolder()->startRenamingSelectedItem();
@ -284,6 +299,10 @@ void LLPanelOutfitsInventory::showEditOutfitPanel()
LLFolderViewEventListener *LLPanelOutfitsInventory::getCorrectListenerForAction()
{
// TODO: add handling "My Outfits" tab.
if (!isCOFPanelActive())
return NULL;
LLFolderViewItem* current_item = getRootFolder()->getCurSelectedItem();
if (!current_item)
return NULL;
@ -311,7 +330,7 @@ bool LLPanelOutfitsInventory::getIsCorrectType(const LLFolderViewEventListener *
LLFolderView *LLPanelOutfitsInventory::getRootFolder()
{
return mActivePanel->getRootFolder();
return getActivePanel()->getRootFolder();
}
//static
@ -393,7 +412,11 @@ void LLPanelOutfitsInventory::onTrashButtonClick()
void LLPanelOutfitsInventory::onClipboardAction(const LLSD& userdata)
{
std::string command_name = userdata.asString();
getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
// TODO: add handling "My Outfits" tab.
if (isCOFPanelActive())
{
getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
}
updateListCommands();
updateVerbs();
}
@ -447,21 +470,26 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
if (command_name == "delete" || command_name == "remove")
{
BOOL can_delete = FALSE;
LLFolderView* root = getActivePanel()->getRootFolder();
if (root)
// TODO: add handling "My Outfits" tab.
if (isCOFPanelActive())
{
std::set<LLUUID> selection_set;
root->getSelectionList(selection_set);
can_delete = (selection_set.size() > 0);
for (std::set<LLUUID>::iterator iter = selection_set.begin();
iter != selection_set.end();
++iter)
LLFolderView* root = getActivePanel()->getRootFolder();
if (root)
{
const LLUUID &item_id = (*iter);
LLFolderViewItem *item = root->getItemByID(item_id);
can_delete &= item->getListener()->isItemRemovable();
std::set<LLUUID> selection_set;
root->getSelectionList(selection_set);
can_delete = (selection_set.size() > 0);
for (std::set<LLUUID>::iterator iter = selection_set.begin();
iter != selection_set.end();
++iter)
{
const LLUUID &item_id = (*iter);
LLFolderViewItem *item = root->getItemByID(item_id);
can_delete &= item->getListener()->isItemRemovable();
}
return can_delete;
}
return can_delete;
}
return FALSE;
}
@ -517,12 +545,17 @@ BOOL LLPanelOutfitsInventory::isActionEnabled(const LLSD& userdata)
bool LLPanelOutfitsInventory::hasItemsSelected()
{
bool has_items_selected = false;
LLFolderView* root = getActivePanel()->getRootFolder();
if (root)
// TODO: add handling "My Outfits" tab.
if (isCOFPanelActive())
{
std::set<LLUUID> selection_set;
root->getSelectionList(selection_set);
has_items_selected = (selection_set.size() > 0);
LLFolderView* root = getActivePanel()->getRootFolder();
if (root)
{
std::set<LLUUID> selection_set;
root->getSelectionList(selection_set);
has_items_selected = (selection_set.size() > 0);
}
}
return has_items_selected;
}
@ -549,74 +582,58 @@ bool LLPanelOutfitsInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropTy
void LLPanelOutfitsInventory::initTabPanels()
{
LLInventoryPanel *cof_panel = getChild<LLInventoryPanel>(COF_TAB_NAME);
cof_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
mTabPanels.push_back(cof_panel);
mCurrentOutfitPanel = getChild<LLInventoryPanel>(COF_TAB_NAME);
mCurrentOutfitPanel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
mCurrentOutfitPanel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onTabSelectionChange, this, mCurrentOutfitPanel, _1, _2));
LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>(OUTFITS_TAB_NAME);
myoutfits_panel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, LLInventoryFilter::FILTERTYPE_CATEGORY);
myoutfits_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
mTabPanels.push_back(myoutfits_panel);
for (tabpanels_vec_t::iterator iter = mTabPanels.begin();
iter != mTabPanels.end();
++iter)
{
LLInventoryPanel *panel = (*iter);
panel->setSelectCallback(boost::bind(&LLPanelOutfitsInventory::onTabSelectionChange, this, panel, _1, _2));
}
mMyOutfitsPanel = getChild<LLOutfitsList>(OUTFITS_TAB_NAME);
mAppearanceTabs = getChild<LLTabContainer>("appearance_tabs");
mAppearanceTabs->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::onTabChange, this));
mActivePanel = (LLInventoryPanel*)mAppearanceTabs->getCurrentPanel();
}
void LLPanelOutfitsInventory::onTabSelectionChange(LLInventoryPanel* tab_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action)
{
if (user_action && items.size() > 0)
{
for (tabpanels_vec_t::iterator iter = mTabPanels.begin();
iter != mTabPanels.end();
++iter)
// TODO: add handling "My Outfits" tab.
if (isCOFPanelActive())
{
LLInventoryPanel *panel = (*iter);
if (panel == tab_panel)
{
mActivePanel = panel;
}
else
{
panel->getRootFolder()->clearSelection();
}
onSelectionChange(items, user_action);
}
else
{
mCurrentOutfitPanel->getRootFolder()->clearSelection();
}
}
onSelectionChange(items, user_action);
}
void LLPanelOutfitsInventory::onTabChange()
{
mActivePanel = (LLInventoryPanel*)childGetVisibleTab("appearance_tabs");
if (!mActivePanel)
// TODO: add handling "My Outfits" tab.
if (isCOFPanelActive())
{
return;
mCurrentOutfitPanel->setFilterSubString(mFilterSubString);
}
mActivePanel->setFilterSubString(mFilterSubString);
else
{
mMyOutfitsPanel->setFilterSubString(mFilterSubString);
}
updateVerbs();
}
BOOL LLPanelOutfitsInventory::isTabPanel(LLInventoryPanel *panel) const
{
for(tabpanels_vec_t::const_iterator it = mTabPanels.begin();
it != mTabPanels.end();
++it)
// TODO: add handling "My Outfits" tab.
if (mCurrentOutfitPanel == panel)
{
if (*it == panel)
return TRUE;
return TRUE;
}
return FALSE;
}
BOOL LLPanelOutfitsInventory::isCOFPanelActive() const
{
return (getActivePanel()->getName() == COF_TAB_NAME);
return (childGetVisibleTab("appearance_tabs")->getName() == COF_TAB_NAME);
}

View File

@ -40,6 +40,7 @@ class LLFolderView;
class LLFolderViewItem;
class LLFolderViewEventListener;
class LLInventoryPanel;
class LLOutfitsList;
class LLSaveFolderState;
class LLButton;
class LLMenuGL;
@ -88,20 +89,21 @@ private:
public:
//////////////////////////////////////////////////////////////////////////////////
// tab panels
LLInventoryPanel* getActivePanel() { return mActivePanel; }
const LLInventoryPanel* getActivePanel() const { return mActivePanel; }
// TODO: change getActivePanel() to return the active tab instead of returning
// a pointer to "Wearing" inventory panel.
LLInventoryPanel* getActivePanel() { return mCurrentOutfitPanel; }
BOOL isTabPanel(LLInventoryPanel *panel) const;
BOOL isCOFPanelActive() const;
protected:
void initTabPanels();
void onTabSelectionChange(LLInventoryPanel* tab_panel, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
void onTabChange();
BOOL isCOFPanelActive() const;
private:
LLInventoryPanel* mActivePanel;
typedef std::vector<LLInventoryPanel *> tabpanels_vec_t;
tabpanels_vec_t mTabPanels;
LLOutfitsList* mMyOutfitsPanel;
LLInventoryPanel* mCurrentOutfitPanel;
// tab panels //
////////////////////////////////////////////////////////////////////////////////

View File

@ -645,6 +645,23 @@ void LLPanelPeople::onChange(EStatusType status, const std::string &channelURI,
updateButtons();
}
void LLPanelPeople::updateFriendListHelpText()
{
// show special help text for just created account to help finding friends. EXT-4836
static LLTextBox* no_friends_text = getChild<LLTextBox>("no_friends_help_text");
// Seems sometimes all_friends can be empty because of issue with Inventory loading (clear cache, slow connection...)
// So, lets check all lists to avoid overlapping the text with online list. See EXT-6448.
bool any_friend_exists = mAllFriendList->filterHasMatches() || mOnlineFriendList->filterHasMatches();
no_friends_text->setVisible(!any_friend_exists);
if (no_friends_text->getVisible())
{
//update help text for empty lists
std::string message_name = mFilterSubString.empty() ? "no_friends_msg" : "no_filtered_friends_msg";
no_friends_text->setText(getString(message_name));
}
}
void LLPanelPeople::updateFriendList()
{
if (!mOnlineFriendList || !mAllFriendList)
@ -684,14 +701,6 @@ void LLPanelPeople::updateFriendList()
online_friendsp.push_back(buddy_id);
}
// show special help text for just created account to help found friends. EXT-4836
static LLTextBox* no_friends_text = getChild<LLTextBox>("no_friends_msg");
// Seems sometimes all_friends can be empty because of issue with Inventory loading (clear cache, slow connection...)
// So, lets check all lists to avoid overlapping the text with online list. See EXT-6448.
bool any_friend_exists = (all_friendsp.size() > 0) || (online_friendsp.size() > 0);
no_friends_text->setVisible(!any_friend_exists);
/*
* Avatarlists will be hidden by showFriendsAccordionsIfNeeded(), if they do not have items.
* But avatarlist can be updated only if it is visible @see LLAvatarList::draw();
@ -1436,6 +1445,9 @@ void LLPanelPeople::showFriendsAccordionsIfNeeded()
// Rearrange accordions
LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("friends_accordion");
accordion->arrange();
// keep help text in a synchronization with accordions visibility.
updateFriendListHelpText();
}
}

View File

@ -73,6 +73,7 @@ private:
} ESortOrder;
// methods indirectly called by the updaters
void updateFriendListHelpText();
void updateFriendList();
void updateNearbyList();
void updateRecentList();

View File

@ -1071,8 +1071,7 @@ void LLPanelPlaces::updateVerbs()
mSaveBtn->setVisible(isLandmarkEditModeOn);
mCancelBtn->setVisible(isLandmarkEditModeOn);
mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
mPlaceInfoBtn->setVisible(mPlaceInfoType != LANDMARK_INFO_TYPE && mPlaceInfoType != TELEPORT_HISTORY_INFO_TYPE
&& !is_create_landmark_visible && !isLandmarkEditModeOn);
mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn);
mShowOnMapBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos);
mPlaceInfoBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos);

View File

@ -539,4 +539,14 @@ bool LLScriptFloaterManager::getFloaterPosition(const LLUUID& object_id, Floater
return false;
}
void LLScriptFloaterManager::setFloaterVisible(const LLUUID& notification_id, bool visible)
{
LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>(
"script_floater", notification_id);
if(floater)
{
floater->setVisible(visible);
}
}
// EOF

View File

@ -99,6 +99,8 @@ public:
bool getFloaterPosition(const LLUUID& object_id, FloaterPositionInfo& fpi);
void setFloaterVisible(const LLUUID& notification_id, bool visible);
protected:
typedef std::map<std::string, EObjectType> object_type_map;

View File

@ -329,8 +329,8 @@ void LLSidepanelAppearance::updateVerbs()
if (mPanelOutfitsInventory && !is_look_info_visible)
{
const bool is_correct_type = (mPanelOutfitsInventory->getCorrectListenerForAction() != NULL);
mEditBtn->setEnabled(is_correct_type);
// const bool is_correct_type = (mPanelOutfitsInventory->getCorrectListenerForAction() != NULL);
// mEditBtn->setEnabled(is_correct_type);
}
else
{

View File

@ -67,6 +67,7 @@ LLToast::Params::Params()
LLToast::LLToast(const LLToast::Params& p)
: LLModalDialog(LLSD(), p.is_modal),
mPanel(p.panel),
mToastLifetime(p.lifetime_secs),
mToastFadingTime(p.fading_time_secs),
mNotificationID(p.notif_id),
mSessionID(p.session_id),
@ -241,6 +242,13 @@ void LLToast::draw()
drawChild(mHideBtn);
}
}
// if timer started and remaining time <= fading time
if (mTimer->getStarted() && (mToastLifetime
- mTimer->getEventTimer().getElapsedTimeF32()) <= mToastFadingTime)
{
setBackgroundOpaque(FALSE);
}
}
//--------------------------------------------------------------------------

View File

@ -209,6 +209,7 @@ private:
// timer counts a lifetime of a toast
std::auto_ptr<LLToastLifeTimer> mTimer;
F32 mToastLifetime; // in seconds
F32 mToastFadingTime; // in seconds
LLPanel* mPanel;

View File

@ -493,7 +493,7 @@ void LLToastNotifyPanel::onClickButton(void* data)
{
sButtonClickSignal(self->mNotification->getID(), button_name);
if(new_info)
if(new_info && !self->mNotification->isPersistent())
{
self->mNotification->setResponseFunctor(
boost::bind(&LLOfferInfo::inventory_offer_callback, new_info, _1, _2));

View File

@ -33,6 +33,7 @@
#include "llviewerprecompiledheaders.h"
#include "llpanelgenerictip.h"
#include "llpanelonlinestatus.h"
#include "llnotifications.h"
#include "lltoastpanel.h"
@ -97,9 +98,19 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification(
{
LLToastPanel* res = NULL;
if (notification->getName() == "SystemMessageTip")
//process tip toast panels
if ("notifytip" == notification->getType())
{
res = new LLPanelGenericTip(notification);
// if it is online/offline notification
if ("FriendOffline" == notification->getName() || "FriendOnline" == notification->getName())
{
res = new LLPanelOnlineStatus(notification);
}
// in all other case we use generic tip panel
else
{
res = new LLPanelGenericTip(notification);
}
}
/*
else if(...)

View File

@ -926,6 +926,7 @@ void link_inventory_item(
const LLUUID& item_id,
const LLUUID& parent_id,
const std::string& new_name,
const std::string& new_description,
const LLAssetType::EType asset_type,
LLPointer<LLInventoryCallback> cb)
{
@ -951,7 +952,6 @@ void link_inventory_item(
}
LLUUID transaction_id;
std::string desc = "Broken link"; // This should only show if the object can't find its baseobj.
LLInventoryType::EType inv_type = LLInventoryType::IT_NONE;
if (dynamic_cast<const LLInventoryCategory *>(baseobj))
{
@ -982,7 +982,7 @@ void link_inventory_item(
msg->addS8Fast(_PREHASH_Type, (S8)asset_type);
msg->addS8Fast(_PREHASH_InvType, (S8)inv_type);
msg->addStringFast(_PREHASH_Name, new_name);
msg->addStringFast(_PREHASH_Description, desc);
msg->addStringFast(_PREHASH_Description, new_description);
}
gAgent.sendReliableMessage();
}

View File

@ -339,6 +339,7 @@ void link_inventory_item(
const LLUUID& item_id,
const LLUUID& parent_id,
const std::string& new_name,
const std::string& new_description,
const LLAssetType::EType asset_type,
LLPointer<LLInventoryCallback> cb);

View File

@ -1035,21 +1035,26 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)
{
// Use the name of the last item giver, who is probably the person
// spamming you.
std::ostringstream message;
message << LLAppViewer::instance()->getSecondLifeTitle();
LLStringUtil::format_map_t arg;
std::string log_msg;
std::ostringstream time ;
time<<OFFER_THROTTLE_TIME;
arg["APP_NAME"] = LLAppViewer::instance()->getSecondLifeTitle();
arg["TIME"] = time.str();
if (!from_name.empty())
{
message << ": Items coming in too fast from " << from_name;
arg["FROM_NAME"] = from_name;
log_msg = LLTrans::getString("ItemsComingInTooFastFrom", arg);
}
else
{
message << ": Items coming in too fast";
log_msg = LLTrans::getString("ItemsComingInTooFast", arg);
}
message << ", automatic preview disabled for "
<< OFFER_THROTTLE_TIME << " seconds.";
//this is kinda important, so actually put it on screen
std::string log_msg = message.str();
LLSD args;
args["MESSAGE"] = log_msg;
LLNotificationsUtil::add("SystemMessage", args);
@ -1247,6 +1252,16 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(blocked_id));
}
LLOfferInfo::LLOfferInfo()
: LLNotificationResponderInterface()
, mFromGroup(FALSE)
, mFromObject(FALSE)
, mIM(IM_NOTHING_SPECIAL)
, mType(LLAssetType::AT_NONE)
, mPersist(false)
{
}
LLOfferInfo::LLOfferInfo(const LLSD& sd)
{
mIM = (EInstantMessage)sd["im_type"].asInteger();
@ -1260,6 +1275,7 @@ LLOfferInfo::LLOfferInfo(const LLSD& sd)
mFromName = sd["from_name"].asString();
mDesc = sd["description"].asString();
mHost = LLHost(sd["sender"].asString());
mPersist = sd["persist"].asBoolean();
}
LLOfferInfo::LLOfferInfo(const LLOfferInfo& info)
@ -1275,6 +1291,7 @@ LLOfferInfo::LLOfferInfo(const LLOfferInfo& info)
mFromName = info.mFromName;
mDesc = info.mDesc;
mHost = info.mHost;
mPersist = info.mPersist;
}
LLSD LLOfferInfo::asLLSD()
@ -1291,9 +1308,15 @@ LLSD LLOfferInfo::asLLSD()
sd["from_name"] = mFromName;
sd["description"] = mDesc;
sd["sender"] = mHost.getIPandPort();
sd["persist"] = mPersist;
return sd;
}
void LLOfferInfo::fromLLSD(const LLSD& params)
{
*this = params;
}
void LLOfferInfo::send_auto_receive_response(void)
{
LLMessageSystem* msg = gMessageSystem;
@ -1333,6 +1356,21 @@ void LLOfferInfo::send_auto_receive_response(void)
}
}
void LLOfferInfo::handleRespond(const LLSD& notification, const LLSD& response)
{
initRespondFunctionMap();
const std::string name = notification["name"].asString();
if(mRespondFunctions.find(name) == mRespondFunctions.end())
{
llwarns << "Unexpected notification name : " << name << llendl;
llassert(!"Unexpected notification name");
return;
}
mRespondFunctions[name](notification, response);
}
bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& response)
{
LLChat chat;
@ -1469,7 +1507,10 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
gInventory.addObserver(opener);
}
delete this;
if(!mPersist)
{
delete this;
}
return false;
}
@ -1635,7 +1676,10 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
gInventory.addObserver(opener);
}
delete this;
if(!mPersist)
{
delete this;
}
return false;
}
@ -1651,6 +1695,15 @@ protected:
}
};
void LLOfferInfo::initRespondFunctionMap()
{
if(mRespondFunctions.empty())
{
mRespondFunctions["ObjectGiveItem"] = boost::bind(&LLOfferInfo::inventory_task_offer_callback, this, _1, _2);
mRespondFunctions["UserGiveItem"] = boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2);
}
}
void inventory_offer_handler(LLOfferInfo* info)
{
//Until throttling is implmented, busy mode should reject inventory instead of silently
@ -1767,7 +1820,8 @@ void inventory_offer_handler(LLOfferInfo* info)
// Inventory Slurls don't currently work for non agent transfers, so only display the object name.
args["ITEM_SLURL"] = msg;
// Note: sets inventory_task_offer_callback as the callback
p.substitutions(args).payload(payload).functor.function(boost::bind(&LLOfferInfo::inventory_task_offer_callback, info, _1, _2));
p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
info->mPersist = true;
p.name = name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser";
// Pop up inv offer chiclet and let the user accept (keep), or reject (and silently delete) the inventory.
LLNotifications::instance().add(p);
@ -1779,7 +1833,8 @@ void inventory_offer_handler(LLOfferInfo* info)
// *TODO fix memory leak
// inventory_offer_callback() is not invoked if user received notification and
// closes viewer(without responding the notification)
p.substitutions(args).payload(payload).functor.function(boost::bind(&LLOfferInfo::inventory_offer_callback, info, _1, _2));
p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
info->mPersist = true;
p.name = "UserGiveItem";
// Prefetch the item into your local inventory.
@ -1800,10 +1855,8 @@ void inventory_offer_handler(LLOfferInfo* info)
// Inform user that there is a script floater via toast system
{
payload["give_inventory_notification"] = TRUE;
LLNotification::Params params(p.name);
params.substitutions = p.substitutions;
params.payload = payload;
LLPostponedNotification::add<LLPostponedOfferNotification>( params, info->mFromID, false);
p.payload = payload;
LLPostponedNotification::add<LLPostponedOfferNotification>(p, info->mFromID, false);
}
}
}
@ -2481,7 +2534,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
// Note: lie to Nearby Chat, pretending that this is NOT an IM, because
// IMs from obejcts don't open IM sessions.
LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
if(nearby_chat)
if(SYSTEM_FROM != name && nearby_chat)
{
LLSD args;
args["owner_id"] = from_id;

View File

@ -40,6 +40,7 @@
#include "lluuid.h"
#include "message.h"
#include "stdenums.h"
#include "llnotifications.h"
//
// Forward declarations
@ -210,11 +211,10 @@ bool highlight_offered_item(const LLUUID& item_id);
void set_dad_inventory_item(LLInventoryItem* inv_item, const LLUUID& into_folder_uuid);
struct LLOfferInfo
class LLOfferInfo : public LLNotificationResponderInterface
{
LLOfferInfo()
: mFromGroup(FALSE), mFromObject(FALSE),
mIM(IM_NOTHING_SPECIAL), mType(LLAssetType::AT_NONE) {};
public:
LLOfferInfo();
LLOfferInfo(const LLSD& sd);
LLOfferInfo(const LLOfferInfo& info);
@ -232,12 +232,27 @@ struct LLOfferInfo
std::string mFromName;
std::string mDesc;
LLHost mHost;
bool mPersist;
// LLNotificationResponderInterface implementation
/*virtual*/ LLSD asLLSD();
/*virtual*/ void fromLLSD(const LLSD& params);
/*virtual*/ void handleRespond(const LLSD& notification, const LLSD& response);
LLSD asLLSD();
void send_auto_receive_response(void);
// TODO - replace all references with handleRespond()
bool inventory_offer_callback(const LLSD& notification, const LLSD& response);
bool inventory_task_offer_callback(const LLSD& notification, const LLSD& response);
private:
void initRespondFunctionMap();
typedef boost::function<bool (const LLSD&, const LLSD&)> respond_function_t;
typedef std::map<std::string, respond_function_t> respond_function_map_t;
respond_function_map_t mRespondFunctions;
};
void process_feature_disabled_message(LLMessageSystem* msg, void**);

View File

@ -1564,10 +1564,6 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
// larger mips are corrupted
priority = -3.0f;
}
else if (cur_discard <= mDesiredDiscardLevel)
{
priority = -4.0f;
}
else
{
// priority range = 100,000 - 500,000

View File

@ -0,0 +1,88 @@
/**
* @file llwearableitemslist.cpp
* @brief A flat list of wearable items.
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "llwearableitemslist.h"
#include "llinventoryfunctions.h"
#include "llinventorymodel.h"
class LLFindOutfitItems : public LLInventoryCollectFunctor
{
public:
LLFindOutfitItems() {}
virtual ~LLFindOutfitItems() {}
virtual bool operator()(LLInventoryCategory* cat,
LLInventoryItem* item);
};
bool LLFindOutfitItems::operator()(LLInventoryCategory* cat,
LLInventoryItem* item)
{
if(item)
{
if((item->getType() == LLAssetType::AT_CLOTHING)
|| (item->getType() == LLAssetType::AT_BODYPART)
|| (item->getType() == LLAssetType::AT_OBJECT))
{
return TRUE;
}
}
return FALSE;
}
static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list");
LLWearableItemsList::LLWearableItemsList(const LLFlatListView::Params& p)
: LLInventoryItemsList(p)
{}
// virtual
LLWearableItemsList::~LLWearableItemsList()
{}
void LLWearableItemsList::updateList(const LLUUID& category_id)
{
LLInventoryModel::cat_array_t cat_array;
LLInventoryModel::item_array_t item_array;
LLFindOutfitItems collector = LLFindOutfitItems();
// collectDescendentsIf takes non-const reference:
gInventory.collectDescendentsIf(
category_id,
cat_array,
item_array,
LLInventoryModel::EXCLUDE_TRASH,
collector);
refreshList(item_array);
}

View File

@ -0,0 +1,56 @@
/**
* @file llwearableitemslist.h
* @brief A flat list of wearable items.
*
* $LicenseInfo:firstyear=2010&license=viewergpl$
*
* Copyright (c) 2010, Linden Research, Inc.
*
* 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
*
* 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
*
* 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.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_LLWEARABLEITEMSLIST_H
#define LL_LLWEARABLEITEMSLIST_H
#include "llpanel.h"
#include "llassettype.h"
#include "llinventorytype.h"
// newview
#include "llinventoryitemslist.h"
class LLWearableItemsList : public LLInventoryItemsList
{
public:
virtual ~LLWearableItemsList();
void updateList(const LLUUID& category_id);
protected:
friend class LLUICtrlFactory;
LLWearableItemsList(const LLFlatListView::Params& p);
};
#endif //LL_LLWEARABLEITEMSLIST_H

View File

@ -1072,18 +1072,10 @@ BOOL LLWorldMapView::handleToolTip( S32 x, S32 y, MASK mask )
// zoomed out, so don't display anything about the count. JC
if (agent_count > 0)
{
// Merov: i18n horror!!! Even using gettext(), concatenating strings is not localizable.
// The singular/plural switch form here under might make no sense in some languages. Don't do that.
message += llformat("\n%d ", agent_count);
if (agent_count == 1)
{
message += "person";
}
else
{
message += "people";
}
LLStringUtil::format_map_t string_args;
string_args["[NUMBER]"] = llformat("%d", agent_count);
message += '\n';
message += getString((agent_count == 1 ? "world_map_person" : "world_map_people") , string_args);
}
}
tooltip_msg.assign( message );

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater customize" title="UDSEENDE" width="509">
<tab_container name="customize tab container" width="507">
<floater name="floater customize" title="UDSEENDE">
<tab_container name="customize tab container">
<text label="Krops Dele" name="body_parts_placeholder">
Kropsdele
</text>
@ -522,7 +522,7 @@
<button label="Vend tilbage" label_selected="Vend tilbage" name="Revert"/>
</panel>
</tab_container>
<scroll_container left="212" name="panel_container"/>
<scroll_container name="panel_container"/>
<button label="Script info" label_selected="Script info" name="script_info" tool_tip="Vis scripts vedhæftet på din avatar"/>
<button label="Lav sæt" label_selected="Lav sæt" name="make_outfit_btn"/>
<button label="Annullér" label_selected="Annullér" name="Cancel"/>

View File

@ -81,7 +81,7 @@
<texture_picker label="Untere Tattoos" name="Lower Tattoos" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/>
<button label="Neue Haut" label_selected="Neue Haut" name="Create New"/>
<button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." left="194" name="Save As" width="105"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/>
<button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/>
</panel>
<panel label="Haar" name="Hair">
@ -116,7 +116,7 @@
<texture_picker label="Textur" name="Texture" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/>
<button label="Neue Haare" label_selected="Neue Haare" name="Create New"/>
<button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." left="194" name="Save As" width="105"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/>
<button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/>
</panel>
<panel label="Augen" name="Eyes">
@ -147,7 +147,7 @@
<texture_picker label="Iris" name="Iris" tool_tip="Klicken Sie hier, um ein Bild auszuwählen"/>
<button label="Neue Augen" label_selected="Neue Augen" name="Create New"/>
<button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." left="194" name="Save As" width="105"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/>
<button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/>
</panel>
<text label="Kleidung" name="clothes_placeholder">
@ -159,7 +159,7 @@
<button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/>
<button label="Neues Hemd" label_selected="Neues Hemd" name="Create New"/>
<button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." left="194" name="Save As" width="105"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/>
<button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/>
<text name="title">
[DESC]
@ -192,7 +192,7 @@
<button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/>
<button label="Neue Hose" label_selected="Neue Hose" name="Create New"/>
<button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." left="194" name="Save As" width="105"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/>
<button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/>
<text name="title">
[DESC]
@ -249,7 +249,7 @@
<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
<button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/>
<button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." left="194" name="Save As" width="105"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/>
<button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/>
</panel>
<panel label="Socken" name="Socks">
@ -282,7 +282,7 @@
<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
<button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/>
<button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." left="194" name="Save As" width="105"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/>
<button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/>
</panel>
<panel label="Jacke" name="Jacket">
@ -316,7 +316,7 @@
<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
<button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/>
<button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." left="194" name="Save As" width="105"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/>
<button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/>
</panel>
<panel label="Handschuhe" name="Gloves">
@ -349,7 +349,7 @@
<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
<button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/>
<button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." left="194" name="Save As" width="105"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/>
<button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/>
</panel>
<panel label="Unterhemd" name="Undershirt">
@ -382,7 +382,7 @@
<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
<button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/>
<button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." left="194" name="Save As" width="105"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/>
<button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/>
</panel>
<panel label="Unterhose" name="Underpants">
@ -415,7 +415,7 @@
<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
<button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/>
<button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." left="194" name="Save As" width="105"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/>
<button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/>
</panel>
<panel label="Rock" name="Skirt">
@ -448,7 +448,7 @@
<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
<button font="SansSerifSmall" label="Ausziehen" label_selected="Ausziehen" name="Take Off"/>
<button font="SansSerifSmall" label="Speichern" label_selected="Speichern" left="107" name="Save"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." left="194" name="Save As" width="105"/>
<button font="SansSerifSmall" label="Speichern unter..." label_selected="Speichern unter..." name="Save As"/>
<button font="SansSerifSmall" label="Zurücksetzen" label_selected="Zurücksetzen" name="Revert"/>
</panel>
<panel label="Tätowierung" name="Tattoo">

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
save_visibility="true"
single_instance="true"
title="CONVERSATIONS"
width="392">
width="396">
<tab_container
follows="left|right|top|bottom"
height="390"
@ -27,7 +27,7 @@
halign="left"
use_ellipses="true"
top="0"
width="390" />
width="394" />
<icon
color="DefaultShadowLight"
enabled="false"
@ -38,5 +38,5 @@
left="1"
name="im_box_tab_container_icon"
bottom="10"
width="390" />
width="394" />
</multi_floater>

View File

@ -13,7 +13,7 @@
can_minimize="true"
can_close="true"
visible="false"
width="385"
width="394"
can_resize="true"
min_width="250"
min_height="190">
@ -22,7 +22,7 @@
default_tab_group="2"
follows="all"
height="320"
width="385"
width="394"
layout="topleft"
orientation="horizontal"
name="im_panels"
@ -43,7 +43,7 @@
tab_group="2"
top="0"
height="200"
width="245"
width="254"
user_resize="true">
<button
height="20"
@ -70,7 +70,7 @@
parse_highlights="true"
allow_html="true"
left="1"
width="240">
width="249">
</chat_history>
<line_editor
bottom="0"
@ -81,7 +81,7 @@
layout="bottomleft"
name="chat_editor"
tab_group="3"
width="240">
width="249">
</line_editor>
</layout_panel>
</layout_stack>

View File

@ -47,7 +47,7 @@
tab_group="1"
tab_position="left"
tab_width="115"
tab_padding_right="5"
tab_padding_right="0"
top="21"
width="658">
<panel

View File

@ -7,7 +7,7 @@
layout="topleft"
name="show_agent">
<menu_item_call.on_click
function="Url.Execute" />
function="Url.ShowProfile" />
</menu_item_call>
<menu_item_separator
layout="topleft" />

View File

@ -7,7 +7,7 @@
layout="topleft"
name="show_group">
<menu_item_call.on_click
function="Url.Execute" />
function="Url.ShowProfile" />
</menu_item_call>
<menu_item_separator
layout="topleft" />

View File

@ -5137,6 +5137,7 @@ No valid parcel could be found.
<notification
icon="notify.tga"
name="ObjectGiveItem"
persist="true"
type="offer">
An object named [OBJECTFROMNAME] owned by [NAME_SLURL] has given you this [OBJECTTYPE]:
[ITEM_SLURL]
@ -5181,6 +5182,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you th
<notification
icon="notify.tga"
name="UserGiveItem"
persist="true"
type="offer">
[NAME_SLURL] has given you this [OBJECTTYPE]:
[ITEM_SLURL]
@ -5233,6 +5235,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you th
<notification
icon="notify.tga"
name="TeleportOffered"
persist="true"
type="offer">
[NAME_SLURL] has offered to teleport you to their location:
@ -5278,6 +5281,7 @@ An object named [OBJECTFROMNAME] owned by (an unknown Resident) has given you th
<notification
icon="notify.tga"
name="OfferFriendship"
persist="true"
type="offer">
[NAME_SLURL] is offering friendship.

View File

@ -3,14 +3,14 @@
border="false"
height="300"
name="panel_im_control_panel"
width="110">
width="119">
<avatar_icon
follows="left|top"
height="105"
left_delta="5"
name="avatar_icon"
top="-5"
width="105"/>
width="114"/>
<layout_stack
mouse_opaque="false"
border_size="0"
@ -22,7 +22,7 @@
name="button_stack"
orientation="vertical"
top_pad="5"
width="105">
width="114">
<layout_panel
mouse_opaque="false"
auto_resize="true"
@ -31,7 +31,7 @@
layout="topleft"
left="2"
min_height="0"
width="100"
width="109"
top="0"
name="spacer"
user_resize="false" />
@ -41,7 +41,7 @@
height="20"
layout="topleft"
min_height="20"
width="100"
width="109"
name="view_profile_btn_panel"
user_resize="false">
<button
@ -50,7 +50,7 @@
label="Profile"
name="view_profile_btn"
top="0"
width="100" />
width="109" />
</layout_panel>
<layout_panel
auto_resize="false"
@ -58,7 +58,7 @@
height="25"
layout="topleft"
min_height="25"
width="100"
width="109"
name="add_friend_btn_panel"
user_resize="false">
<button
@ -67,7 +67,7 @@
label="Add Friend"
name="add_friend_btn"
top="5"
width="100" />
width="109" />
</layout_panel>
<layout_panel
auto_resize="false"
@ -75,7 +75,7 @@
height="25"
layout="topleft"
min_height="25"
width="100"
width="109"
name="teleport_btn_panel"
user_resize="false">
<button
@ -85,7 +85,7 @@
label="Teleport"
name="teleport_btn"
tool_tip = "Offer to teleport this person"
width="100" />
width="109" />
</layout_panel>
<layout_panel
auto_resize="false"
@ -93,7 +93,7 @@
height="25"
layout="topleft"
min_height="25"
width="100"
width="109"
name="share_btn_panel"
user_resize="false">
<button
@ -102,7 +102,7 @@
height="23"
label="Share"
name="share_btn"
width="100" />
width="109" />
</layout_panel>
<layout_panel
auto_resize="false"
@ -110,7 +110,7 @@
height="25"
layout="topleft"
min_height="25"
width="100"
width="109"
name="pay_btn_panel"
user_resize="false">
<button
@ -119,7 +119,7 @@
height="23"
label="Pay"
name="pay_btn"
width="100" />
width="109" />
</layout_panel>
<layout_panel
auto_resize="false"
@ -127,7 +127,7 @@
height="25"
layout="topleft"
min_height="25"
width="100"
width="109"
name="call_btn_panel"
user_resize="false">
<button
@ -135,7 +135,7 @@
height="23"
label="Call"
name="call_btn"
width="100" />
width="109" />
</layout_panel>
<layout_panel
auto_resize="false"
@ -143,7 +143,7 @@
height="25"
layout="topleft"
min_height="25"
width="100"
width="109"
name="end_call_btn_panel"
user_resize="false"
visible="false">
@ -152,7 +152,7 @@
height="23"
label="End Call"
name="end_call_btn"
width="100" />
width="109" />
</layout_panel>
<layout_panel
auto_resize="false"
@ -160,7 +160,7 @@
height="25"
layout="topleft"
min_height="25"
width="100"
width="109"
name="voice_ctrls_btn_panel"
user_resize="false"
visible="false">
@ -169,7 +169,7 @@
height="23"
label="Voice Controls"
name="voice_ctrls_btn"
width="100" />
width="109" />
</layout_panel>
</layout_stack>
</panel>

View File

@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
follows="top|right|left"
height="20"
layout="topleft"
left="0"
name="inventory_item"
top="0"
width="380">
<icon
follows="top|right|left"
height="20"
image_name="ListItem_Over"
layout="topleft"
left="0"
name="hovered_icon"
top="0"
visible="false"
width="380" />
<icon
height="20"
follows="top|right|left"
image_name="ListItem_Select"
layout="topleft"
left="0"
name="selected_icon"
top="0"
visible="false"
width="380" />
<icon
height="16"
follows="top|left"
image_name="Inv_Object"
layout="topleft"
left="0"
name="item_icon"
top="0"
width="16" />
<text
follows="left|right"
height="20"
layout="topleft"
left_pad="5"
allow_html="false"
use_ellipses="true"
name="item_name"
text_color="white"
top="4"
value="..."
width="359" />
</panel>

View File

@ -401,14 +401,6 @@
name="edit_profile_btn"
tool_tip="Edit your personal information"
width="152" />
<button
follows="bottom|right"
height="23"
label="Edit Appearance"
left_pad="3"
name="edit_appearance_btn"
tool_tip="Create/edit your appearance: physical data, clothes and etc."
width="153" />
</layout_panel>
</layout_stack>
</panel>

View File

@ -7,7 +7,7 @@
background_opaque="true"
background_visible="true"
layout="topleft"
width="270"
width="328"
height="230"
name="nearby_media"
help_topic="nearby_media">
@ -29,7 +29,7 @@
follows="left"
tool_tip="Turn all nearby media off"
left="8"
width="66"
width="95"
height="22"
label="Stop All">
<button.commit_callback
@ -40,7 +40,7 @@
follows="left"
tool_tip="Turn all nearby media on"
left_pad="4"
width="66"
width="95"
height="22"
label="Start All">
<button.commit_callback

View File

@ -341,6 +341,30 @@
top_pad="5"
width="300"/>
<panel
name="filtered_wearables_panel"
background_opaque="true"
background_visible="true"
layout="topleft"
follows="left|top|right|bottom"
border="false"
height="155"
left="0"
mouse_opaque="false"
width="300"
top_delta="0"
visible="false">
<wearable_items_list
name="filtered_wearables_list"
allow_select="true"
layout="topleft"
follows="all"
width="300"
height="155"
left="0"
top="0" />
</panel>
<panel
background_visible="true"
bevel_style="none"

View File

@ -23,20 +23,16 @@
tab_position="top"
halign="center"
width="312">
<inventory_panel
background_visible="true"
background_opaque="true"
label="MY OUTFITS"
help_topic="my_outfits_tab"
allow_multi_select="true"
follows="all"
border="false"
left="0"
top="0"
width="315"
mouse_opaque="true"
<panel
class="outfits_list"
filename="panel_outfits_list.xml"
height="490"
name="outfitslist_tab"
start_folder="My Outfits" />
background_visible="true"
follows="all"
label="MY OUTFITS"
layout="topleft"
width="315" />
<inventory_panel
follows="all"
background_visible="true"

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<panel
background_visible="true"
bg_alpha_color="DkGray"
border="false"
follows="all"
height="400"
name="Outfits"
layout="topleft"
left="0"
top="0"
width="313">
<accordion
background_visible="true"
bg_alpha_color="DkGray2"
bg_opaque_color="DkGray2"
follows="all"
height="400"
layout="topleft"
left="3"
name="outfits_accordion"
top="0"
width="307">
</accordion>
</panel>

View File

@ -29,6 +29,15 @@
<string
name="no_friends"
value="No friends" />
<string
name="no_friends_msg">
Find friends using [secondlife:///app/search/people Search] or right-click on a Resident to add them as a friend.
Looking for people to hang out with? Try the [secondlife:///app/worldmap World Map].
</string>
<string
name="no_filtered_friends_msg">
Didn't find what you're looking for? Try [secondlife:///app/search/people Search].
</string>
<string
name="people_filter_label"
value="Filter People" />
@ -265,14 +274,11 @@
<text
follows="all"
height="450"
left="10"
name="no_friends_msg"
left="13"
name="no_friends_help_text"
top="10"
width="293"
wrap="true">
Find friends using [secondlife:///app/search/people Search] or right-click on a Resident to add them as a friend.
Looking for people to hang out with? Try the [secondlife:///app/worldmap World Map].
</text>
wrap="true" />
</panel>
<panel
background_opaque="true"
@ -293,6 +299,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
Values are set from appropriate strings at the top of file via LLPeoplePanel::postBuild()
-->
<group_list
allow_select="true"
background_visible="true"
bg_alpha_color="DkGray2"
bg_opaque_color="DkGray2"

View File

@ -389,14 +389,6 @@
name="edit_profile_btn"
tool_tip="Edit your personal information"
width="130" />
<button
follows="bottom|right"
height="23"
label="Edit Appearance"
left_pad="10"
name="edit_appearance_btn"
tool_tip="Create/edit your appearance: physical data, clothes and etc."
width="130" />
</layout_panel>
</layout_stack>

View File

@ -45,6 +45,14 @@
name="world_map_northwest">
NW
</panel.string>
<panel.string
name="world_map_person">
1 person
</panel.string>
<panel.string
name="world_map_people">
[NUMBER] people
</panel.string>
<text
type="string"
length="1"

View File

@ -1851,7 +1851,7 @@ Clears (deletes) the media and all params from the given face.
<string name="LeaveMouselook">Press ESC to return to World View</string>
<!-- inventory -->
<string name="InventoryNoMatchingItems">No matching items found in inventory. Try [secondlife:///app/search/groups "Search"].</string>
<string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all Search].</string>
<string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string>
<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string>
<!-- use value="" because they have preceding spaces -->
@ -2906,6 +2906,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
<string name="LocationCtrlBuildTooltip">Building/dropping objects not allowed</string>
<string name="LocationCtrlScriptsTooltip">Scripts not allowed</string>
<string name="LocationCtrlDamageTooltip">Health</string>
<string name="LocationCtrlAdultIconTooltip">Adult Region</string>
<string name="LocationCtrlModerateIconTooltip">Moderate Region</string>
<string name="LocationCtrlGeneralIconTooltip">General Region</string>
<!-- Strings used by the (currently Linux) auto-updater app -->
<string name="UpdaterWindowTitle">
@ -2939,6 +2942,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
Failed to start viewer
</string>
<!-- System Messages -->
<string name="ItemsComingInTooFastFrom">[APP_NAME]: Items coming in too fast from [FROM_NAME], automatic preview disabled for [TIME] seconds</string>
<string name="ItemsComingInTooFast">[APP_NAME]: Items coming in too fast, automatic preview disabled for [TIME] seconds</string>
<!-- IM system messages -->
<string name="IM_logging_string">-- Instant message logging enabled --</string>
<string name="IM_typing_start_string">[NAME] is typing...</string>

View File

@ -6,6 +6,8 @@
<location_input font="SansSerifSmall"
icon_maturity_general="Parcel_PG_Light"
icon_maturity_adult="Parcel_R_Light"
icon_maturity_moderate="Parcel_M_Light"
maturity_help_topic="TODO"
add_landmark_image_enabled="Favorite_Star_Active"
add_landmark_image_disabled="Favorite_Star_Off"
add_landmark_image_hover="Favorite_Star_Over"
@ -43,7 +45,7 @@
scale_image="false"
top="19"
left="-3" />
<maturity_icon
<maturity_button
name="maturity_icon"
width="18"
height="16"

View File

@ -81,7 +81,7 @@
<texture_picker label="Tatuaje: inferior" name="Lower Tattoos" tool_tip="Pulse para elegir una imagen" width="90"/>
<button label="Crear una piel nueva" label_selected="Crear una piel nueva" name="Create New"/>
<button label="Guardar" label_selected="Guardar" left="113" name="Save"/>
<button label="Guardar como..." label_selected="Guardar como..." left="199" name="Save As" width="102"/>
<button label="Guardar como..." label_selected="Guardar como..." name="Save As"/>
<button label="Restablecer" label_selected="Restablecer" name="Revert"/>
</panel>
<panel label="Pelo" name="Hair">
@ -116,7 +116,7 @@
<texture_picker label="Textura" name="Texture" tool_tip="Pulse para elegir una imagen"/>
<button label="Crear un pelo nuevo" label_selected="Crear un pelo nuevo" name="Create New"/>
<button label="Guardar" label_selected="Guardar" left="113" name="Save"/>
<button label="Guardar como..." label_selected="Guardar como..." left="199" name="Save As" width="102"/>
<button label="Guardar como..." label_selected="Guardar como..." name="Save As"/>
<button label="Restablecer" label_selected="Restablecer" name="Revert"/>
</panel>
<panel label="Ojos" name="Eyes">
@ -147,7 +147,7 @@
<texture_picker label="Iris" name="Iris" tool_tip="Pulse para elegir una imagen"/>
<button label="Crear unos ojos nuevos" label_selected="Crear unos ojos nuevos" name="Create New"/>
<button label="Guardar" label_selected="Guardar" left="113" name="Save"/>
<button label="Guardar como..." label_selected="Guardar como..." left="199" name="Save As" width="102"/>
<button label="Guardar como..." label_selected="Guardar como..." name="Save As"/>
<button label="Restablecer" label_selected="Restablecer" name="Revert"/>
</panel>
<text label="Ropa" name="clothes_placeholder">
@ -159,7 +159,7 @@
<button label="Quitarla" label_selected="Quitarla" name="Take Off"/>
<button label="Crear una falda nueva" label_selected="Crear una falda nueva" name="Create New"/>
<button label="Guardar" label_selected="Guardar" left="113" name="Save"/>
<button label="Guardar como..." label_selected="Guardar como..." left="199" name="Save As" width="102"/>
<button label="Guardar como..." label_selected="Guardar como..." name="Save As"/>
<button label="Restablecer" label_selected="Restablecer" name="Revert"/>
<text name="title">
[DESC]
@ -192,7 +192,7 @@
<button label="Quitarlos" label_selected="Quitarlos" name="Take Off"/>
<button label="Crear unos pantalones nuevos" label_selected="Crear unos pantalones nuevos" name="Create New" width="185"/>
<button label="Guardar" label_selected="Guardar" left="113" name="Save"/>
<button label="Guardar como..." label_selected="Guardar como..." left="199" name="Save As" width="102"/>
<button label="Guardar como..." label_selected="Guardar como..." name="Save As"/>
<button label="Restablecer" label_selected="Restablecer" name="Revert"/>
<text name="title">
[DESC]
@ -249,7 +249,7 @@
<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
<button label="Quitarlos" label_selected="Quitarlos" name="Take Off"/>
<button label="Guardar" label_selected="Guardar" left="113" name="Save"/>
<button label="Guardar como..." label_selected="Guardar como..." left="199" name="Save As" width="102"/>
<button label="Guardar como..." label_selected="Guardar como..." name="Save As"/>
<button label="Restablecer" label_selected="Restablecer" name="Revert"/>
</panel>
<panel label="Calcetines" name="Socks">
@ -282,7 +282,7 @@
<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
<button label="Quitarlos" label_selected="Quitarlos" name="Take Off"/>
<button label="Guardar" label_selected="Guardar" left="113" name="Save"/>
<button label="Guardar como..." label_selected="Guardar como..." left="199" name="Save As" width="102"/>
<button label="Guardar como..." label_selected="Guardar como..." name="Save As"/>
<button label="Restablecer" label_selected="Restablecer" name="Revert"/>
</panel>
<panel label="Chaqueta" name="Jacket">
@ -316,7 +316,7 @@
<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
<button label="Quitarla" label_selected="Quitarla" name="Take Off"/>
<button label="Guardar" label_selected="Guardar" left="113" name="Save"/>
<button label="Guardar como..." label_selected="Guardar como..." left="199" name="Save As" width="102"/>
<button label="Guardar como..." label_selected="Guardar como..." name="Save As"/>
<button label="Restablecer" label_selected="Restablecer" name="Revert"/>
</panel>
<panel label="Guantes" name="Gloves">
@ -349,7 +349,7 @@
<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
<button label="Quitarlos" label_selected="Quitarlos" name="Take Off"/>
<button label="Guardar" label_selected="Guardar" left="113" name="Save"/>
<button label="Guardar como..." label_selected="Guardar como..." left="199" name="Save As" width="102"/>
<button label="Guardar como..." label_selected="Guardar como..." name="Save As"/>
<button label="Restablecer" label_selected="Restablecer" name="Revert"/>
</panel>
<panel label="Camiseta" name="Undershirt">
@ -382,7 +382,7 @@
<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
<button label="Quitarla" label_selected="Quitarla" name="Take Off"/>
<button label="Guardar" label_selected="Guardar" left="113" name="Save"/>
<button label="Guardar como..." label_selected="Guardar como..." left="199" name="Save As" width="102"/>
<button label="Guardar como..." label_selected="Guardar como..." name="Save As"/>
<button label="Restablecer" label_selected="Restablecer" name="Revert"/>
</panel>
<panel label="Ropa interior" name="Underpants">
@ -415,7 +415,7 @@
<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
<button label="Quitarla" label_selected="Quitarla" name="Take Off"/>
<button label="Guardar" label_selected="Guardar" left="113" name="Save"/>
<button label="Guardar como..." label_selected="Guardar como..." left="199" name="Save As" width="102"/>
<button label="Guardar como..." label_selected="Guardar como..." name="Save As"/>
<button label="Restablecer" label_selected="Restablecer" name="Revert"/>
</panel>
<panel label="Falda" name="Skirt">
@ -448,7 +448,7 @@
<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
<button label="Quitarla" label_selected="Quitarla" name="Take Off"/>
<button label="Guardar" label_selected="Guardar" left="113" name="Save"/>
<button label="Guardar como..." label_selected="Guardar como..." left="199" name="Save As" width="102"/>
<button label="Guardar como..." label_selected="Guardar como..." name="Save As"/>
<button label="Restablecer" label_selected="Restablecer" name="Revert"/>
</panel>
<panel label="Tatuaje" name="Tattoo">

View File

@ -25,7 +25,7 @@
<text left="8" name="Current color:">
Couleur actuelle :
</text>
<text left="8" name="(Drag below to save.)" width="220">
<text name="(Drag below to save.)">
Enr. : faire glisser dessous
</text>
</floater>

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater customize" title="APPARENCE" width="548">
<tab_container name="customize tab container" tab_min_width="150" width="546">
<floater name="floater customize" title="APPARENCE">
<tab_container name="customize tab container" tab_min_width="150">
<text label="Parties du corps" name="body_parts_placeholder">
Parties du corps
</text>
<panel label="Silhouette" left="154" name="Shape" width="389">
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
<button label="Corps" label_selected="Corps" name="Body"/>
<button label="Tête" label_selected="Tête" name="Head"/>
<button label="Yeux" label_selected="Yeux" name="Eyes"/>
@ -44,8 +44,8 @@
Silhouette :
</text>
<button label="Créer une silhouette" label_selected="Créer une silhouette" name="Create New"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
</panel>
<panel label="Peau" name="Skin">
<button label="Couleur" label_selected="Couleur" name="Skin Color" width="84"/>
@ -80,9 +80,9 @@
<texture_picker label="Tatouages haut" name="Upper Tattoos" tool_tip="Cliquez pour sélectionner une image" width="78"/>
<texture_picker label="Tatouages bas" name="Lower Tattoos" tool_tip="Cliquez pour sélectionner une image" width="78"/>
<button label="Créer une peau" label_selected="Créer une peau" name="Create New"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
</panel>
<panel label="Cheveux" name="Hair">
<button label="Couleur" label_selected="Couleur" name="Color"/>
@ -115,9 +115,9 @@
</text>
<texture_picker label="Texture" name="Texture" tool_tip="Cliquez pour sélectionner une image"/>
<button label="Créer des cheveux" label_selected="Créer des cheveux" name="Create New"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
</panel>
<panel label="Yeux" name="Eyes">
<text name="title">
@ -146,9 +146,9 @@
</text>
<texture_picker label="Iris" name="Iris" tool_tip="Cliquez pour sélectionner une image"/>
<button label="Créer des yeux" label_selected="Créer des yeux" name="Create New"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
</panel>
<text label="Habits" name="clothes_placeholder">
Habits
@ -158,9 +158,9 @@
<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/>
<button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/>
<button label="Créer une chemise" label_selected="Créer une chemise" name="Create New"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
<text name="title">
[DESC]
</text>
@ -191,9 +191,9 @@
<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/>
<button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/>
<button label="Créer un pantalon" label_selected="Créer un pantalon" name="Create New"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
<text name="title">
[DESC]
</text>
@ -248,9 +248,9 @@
<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/>
<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/>
<button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
</panel>
<panel label="Chaussettes" name="Socks">
<text name="title">
@ -281,9 +281,9 @@
<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/>
<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/>
<button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
</panel>
<panel label="Veste" name="Jacket">
<text name="title">
@ -315,9 +315,9 @@
<texture_picker label="Tissu (dessous)" name="Lower Fabric" tool_tip="Cliquez pour sélectionner une image" width="81"/>
<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="81"/>
<button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
</panel>
<panel label="Gants" name="Gloves">
<text name="title">
@ -348,9 +348,9 @@
<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/>
<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/>
<button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
</panel>
<panel label="Débardeur" name="Undershirt">
<text name="title">
@ -375,15 +375,15 @@
<text name="no modify instructions">
Vous n&apos;avez pas la permission de modifier cet objet.
</text>
<text bottom="-470" name="Item Action Label" right="92">
<text name="Item Action Label">
Débardeur :
</text>
<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/>
<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/>
<button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
</panel>
<panel label="Caleçon" name="Underpants">
<text name="title">
@ -408,15 +408,15 @@
<text name="no modify instructions">
Vous n&apos;avez pas la permission de modifier cet objet.
</text>
<text bottom="-470" name="Item Action Label" right="92">
<text name="Item Action Label">
Caleçon :
</text>
<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/>
<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/>
<button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
</panel>
<panel label="Jupe" name="Skirt">
<text name="title">
@ -447,9 +447,9 @@
<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image" width="74"/>
<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="74"/>
<button label="Enlever" label_selected="Enlever" left="12" name="Take Off" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" left="100" name="Save" width="82"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." left="188" name="Save As" width="111"/>
<button label="Rétablir" label_selected="Rétablir" left="305" name="Revert" width="82"/>
<button label="Enregistrer" label_selected="Enregistrer" name="Save"/>
<button label="Enregistrer sous..." label_selected="Enregistrer sous..." name="Save As"/>
<button label="Rétablir" label_selected="Rétablir" name="Revert"/>
</panel>
<panel label="Tatouage" name="Tattoo">
<text name="title">

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater customize" title="ASPETTO" width="551">
<tab_container name="customize tab container" tab_min_width="120" width="549">
<floater name="floater customize" title="ASPETTO">
<tab_container name="customize tab container" tab_min_width="120">
<text label="Parti del corpo" name="body_parts_placeholder">
Parti del corpo
</text>
<panel label="Forma del corpo" left="124" name="Shape" width="389">
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<panel label="Forma del corpo" left="124" name="Shape">
<button label="Crea una nuova forma del corpo" label_selected="Crea una nuova forma del corpo" name="Create New" width="190"/>
<button label="Corpo" label_selected="Corpo" name="Body"/>
<button label="Testa" label_selected="Testa" name="Head"/>
<button label="Occhi" label_selected="Occhi" name="Eyes"/>
@ -40,12 +40,12 @@
<text name="no modify instructions">
Non hai il permesso di modificare questo indumento.
</text>
<text name="Item Action Label" right="89">
<text name="Item Action Label">
Forma del corpo:
</text>
<button label="Crea una nuova forma del corpo" label_selected="Crea una nuova forma del corpo" name="Create New" width="190"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert"/>
</panel>
<panel label="Pelle" name="Skin">
<button label="Colore della pelle" label_selected="Colore della pelle" name="Skin Color" width="115"/>
@ -80,9 +80,9 @@
<texture_picker label="Tatuaggi: superiori" name="Upper Tattoos" tool_tip="Clicca per scegliere un&apos;immagine" width="96"/>
<texture_picker label="Tatuaggi: inferiori" name="Lower Tattoos" tool_tip="Clicca per scegliere un&apos;immagine" width="96"/>
<button label="Crea una nuova pelle" label_selected="Crea una nuova pelle" name="Create New"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert"/>
</panel>
<panel label="Capelli" name="Hair">
<button label="Capelli" label_selected="Colore" name="Color"/>
@ -115,9 +115,9 @@
</text>
<texture_picker label="Texture" name="Texture" tool_tip="Clicca per scegliere un&apos;immagine"/>
<button label="Crea nuovi capelli" label_selected="Crea nuovi capelli" name="Create New"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert" width="120"/>
</panel>
<panel label="Occhi" name="Eyes">
<text name="title">
@ -146,9 +146,9 @@
</text>
<texture_picker label="Iride" name="Iris" tool_tip="Clicca per scegliere un&apos;immagine"/>
<button label="Crea nuovi occhi" label_selected="Crea nuovi occhi" name="Create New"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert" width="120"/>
</panel>
<text label="Vestiti" name="clothes_placeholder">
Abiti
@ -158,9 +158,9 @@
<color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Clicca per aprire il selettore dei colori"/>
<button label="Togli" label_selected="Togli" name="Take Off"/>
<button label="Crea una nuova camicia" label_selected="Crea una nuova camicia" name="Create New"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert" width="120"/>
<text name="title">
[DESC]
</text>
@ -191,9 +191,9 @@
<color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Clicca per aprire il selettore dei colori"/>
<button label="Togli" label_selected="Togli" name="Take Off"/>
<button label="Crea nuovi pantaloni" label_selected="Crea nuovi pantaloni" name="Create New"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert" width="120"/>
<text name="title">
[DESC]
</text>
@ -248,9 +248,9 @@
<texture_picker label="Tessuto" name="Fabric" tool_tip="Clicca per scegliere un&apos;immagine"/>
<color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Clicca per aprire il selettore dei colori"/>
<button label="Togli" label_selected="Togli" name="Take Off"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert" width="120"/>
</panel>
<panel label="Calze" name="Socks">
<text name="title">
@ -281,9 +281,9 @@
<texture_picker label="Tessuto" name="Fabric" tool_tip="Clicca per scegliere un&apos;immagine"/>
<color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Clicca per aprire il selettore dei colori"/>
<button label="Togli" label_selected="Togli" name="Take Off"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert" width="120"/>
</panel>
<panel label="Giacca" name="Jacket">
<text name="title">
@ -315,9 +315,9 @@
<texture_picker label="Tessuto: inferiore" name="Lower Fabric" tool_tip="Clicca per scegliere un&apos;immagine" width="96"/>
<color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Clicca per aprire il selettore dei colori"/>
<button label="Togli" label_selected="Togli" name="Take Off"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert" width="120"/>
</panel>
<panel label="Guanti" name="Gloves">
<text name="title">
@ -348,9 +348,9 @@
<texture_picker label="Tessuto" name="Fabric" tool_tip="Clicca per scegliere un&apos;immagine"/>
<color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Clicca per aprire il selettore dei colori"/>
<button font="SansSerifSmall" label="Rimuovi l&apos;indumento" label_selected="Rimuovi l&apos;indumento" name="Take Off" width="115"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert" width="120"/>
</panel>
<panel label="Canottiera" name="Undershirt">
<text name="title">
@ -381,9 +381,9 @@
<texture_picker label="Tessuto" name="Fabric" tool_tip="Clicca per scegliere un&apos;immagine"/>
<color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Clicca per aprire il selettore dei colori"/>
<button font="SansSerifSmall" label="Rimuovi l&apos;indumento" label_selected="Rimuovi l&apos;indumento" name="Take Off" width="115"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert" width="120"/>
</panel>
<panel label="Mutande" name="Underpants">
<text name="title">
@ -414,9 +414,9 @@
<texture_picker label="Tessuto" name="Fabric" tool_tip="Clicca per scegliere un&apos;immagine"/>
<color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Clicca per aprire il selettore dei colori"/>
<button font="SansSerifSmall" label="Rimuovi l&apos;indumento" label_selected="Rimuovi l&apos;indumento" name="Take Off" width="115"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert" width="120"/>
</panel>
<panel label="Gonna" name="Skirt">
<text name="title">
@ -447,9 +447,9 @@
<texture_picker label="Tessuto" name="Fabric" tool_tip="Clicca per scegliere un&apos;immagine"/>
<color_swatch label="Colore/Tinta" name="Color/Tint" tool_tip="Clicca per aprire il selettore dei colori"/>
<button font="SansSerifSmall" label="Rimuovi l&apos;indumento" label_selected="Rimuovi l&apos;indumento" name="Take Off" width="115"/>
<button label="Salva" label_selected="Salva" left="95" name="Save" width="72"/>
<button label="Salva" label_selected="Salva" name="Save"/>
<button label="Salva come..." label_selected="Salva come..." left="171" name="Save As"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" left="267" name="Revert" width="120"/>
<button font="SansSerifSmall" label="Annulla le modifiche" label_selected="Annulla le modifiche" name="Revert" width="120"/>
</panel>
<panel label="Tatuaggio" name="Tattoo">
<text name="title">
@ -522,7 +522,7 @@
<button label="Ripristina" label_selected="Ripristina" name="Revert"/>
</panel>
</tab_container>
<scroll_container left="254" name="panel_container"/>
<scroll_container name="panel_container"/>
<button label="Informazioni script" label_selected="Informazioni script" name="script_info" tool_tip="Mostra gli script collegati al tuo avatar"/>
<button label="Crea vestiario" label_selected="Crea vestiario" name="make_outfit_btn"/>
<button label="Annulla" label_selected="Annulla" name="Cancel"/>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater customize" title="UITERLIJK" width="551">
<tab_container name="customize tab container" tab_min_width="120" width="549">
<floater name="floater customize" title="UITERLIJK">
<tab_container name="customize tab container" tab_min_width="120">
<placeholder label="Lichaamsdelen" name="body_parts_placeholder"/>
<panel label="Postuur" name="Shape" left="124" width="389">
<button label="Herstel" label_selected="Herstel" name="Revert"/>
@ -462,7 +462,7 @@ slepen. Ook kunt u zelf van begin af aan een nieuwe creëren en dragen.
<button label="Herstel" label_selected="Herstel" name="Revert"/>
</panel>
</tab_container>
<scroll_container left="254" name="panel_container"/>
<scroll_container name="panel_container"/>
<button label="Annuleren" label_selected="Annuleren" name="Cancel"/>
<button label="OK" label_selected="OK" name="Ok"/>
<button label="Maak kleding..." label_selected="Maak kleding..." name="Make Outfit" left="110"/>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="floater customize" title="APARÊNCIA" width="546">
<tab_container name="customize tab container" tab_min_width="115" width="544">
<floater name="floater customize" title="APARÊNCIA">
<tab_container name="customize tab container" tab_min_width="115">
<text label="Corpo" name="body_parts_placeholder">
Partes do corpo
</text>