Merge viewer-neko

master
Ansariel 2019-09-06 19:58:23 +02:00
commit c62ef0981b
16 changed files with 344 additions and 150 deletions

View File

@ -32,6 +32,8 @@
#include "llagent.h"
#include "llappearancemgr.h"
#include "lllineeditor.h"
#include "llnotificationsutil.h"
#include "llnotifications.h"
#include "lltextbox.h"
#include "llviewercontrol.h"
@ -181,40 +183,75 @@ void LLFloaterLinkReplace::onStartClicked()
LL_WARNS() << "Cannot replace. Source and target are identical." << LL_ENDL;
return;
}
const LLUUID& source_item_id = gInventory.getLinkedItemID(mSourceUUID);
LLViewerInventoryItem *source_item = gInventory.getItem(source_item_id);
const LLUUID& target_item_id = gInventory.getLinkedItemID(mTargetUUID);
LLViewerInventoryItem *target_item = gInventory.getItem(target_item_id);
LLInventoryModel::cat_array_t cat_array;
LLLinkedItemIDMatches is_linked_item_match(mSourceUUID);
gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cat_array,
mRemainingInventoryItems,
LLInventoryModel::INCLUDE_TRASH,
is_linked_item_match);
LL_INFOS() << "Found " << mRemainingInventoryItems.size() << " inventory links that need to be replaced." << LL_ENDL;
if (mRemainingInventoryItems.size() > 0)
LLNotification::Params params("ConfirmReplaceLink");
params.functor.function(boost::bind(&LLFloaterLinkReplace::onStartClickedResponse, this, _1, _2));
if (source_item && source_item->isWearableType() && source_item->getWearableType() <= LLWearableType::WT_EYES)
{
LLViewerInventoryItem* target_item = gInventory.getItem(mTargetUUID);
// <FS:Beq> FIRE-17695 - option to bulk delete links.
//if (target_item)
if (target_item || mDeleteOnly)
// </FS:Beq>
if(target_item && target_item->isWearableType() && source_item->getWearableType() == target_item->getWearableType())
{
mRemainingItems = (U32)mRemainingInventoryItems.size();
LLStringUtil::format_map_t args;
args["NUM"] = llformat("%d", mRemainingItems);
mStatusText->setText(getString("ItemsRemaining", args));
mStartBtn->setEnabled(FALSE);
mRefreshBtn->setEnabled(FALSE);
mEventTimer.start();
tick();
LLNotifications::instance().forceResponse(params, 0);
}
else
{
mStatusText->setText(getString("TargetNotFound"));
LL_WARNS() << "Link replace target not found." << LL_ENDL;
LLSD args;
args["TYPE"] = LLWearableType::getTypeName(source_item->getWearableType());
params.substitutions(args);
LLNotifications::instance().add(params);
}
}
else
{
LLNotifications::instance().forceResponse(params, 0);
}
}
void LLFloaterLinkReplace::onStartClickedResponse(const LLSD& notification, const LLSD& response)
{
if (LLNotificationsUtil::getSelectedOption(notification, response) == 0)
{
LLInventoryModel::cat_array_t cat_array;
LLLinkedItemIDMatches is_linked_item_match(mSourceUUID);
gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
cat_array,
mRemainingInventoryItems,
LLInventoryModel::INCLUDE_TRASH,
is_linked_item_match);
LL_INFOS() << "Found " << mRemainingInventoryItems.size() << " inventory links that need to be replaced." << LL_ENDL;
if (mRemainingInventoryItems.size() > 0)
{
LLViewerInventoryItem* target_item = gInventory.getItem(mTargetUUID);
// <FS:Beq> FIRE-17695 - option to bulk delete links.
//if (target_item)
if (target_item || mDeleteOnly)
// </FS:Beq>
{
mRemainingItems = (U32)mRemainingInventoryItems.size();
LLStringUtil::format_map_t args;
args["NUM"] = llformat("%d", mRemainingItems);
mStatusText->setText(getString("ItemsRemaining", args));
mStartBtn->setEnabled(FALSE);
mRefreshBtn->setEnabled(FALSE);
mEventTimer.start();
tick();
}
else
{
mStatusText->setText(getString("TargetNotFound"));
LL_WARNS() << "Link replace target not found." << LL_ENDL;
}
}
}
}

View File

@ -95,6 +95,7 @@ public:
private:
void checkEnableStart();
void onStartClicked();
void onStartClickedResponse(const LLSD& notification, const LLSD& response);
void decreaseOpenItemCount();
void updateFoundLinks();
void processBatch(LLInventoryModel::item_array_t items);

View File

@ -62,9 +62,8 @@ static const S32 HPAD = 25;
static const S32 BTN_HPAD = 8;
LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal)
: LLToastPanel(notification),
: LLCheckBoxToastPanel(notification),
mDefaultOption( 0 ),
mCheck(NULL),
mCaution(notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH),
mLabel(notification->getName()),
mLineEditor(NULL)
@ -361,20 +360,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
}
}
std::string ignore_label;
if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
{
setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label);
}
if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY)
{
setCheckBox(LLNotifications::instance().getGlobalString("skipnexttimesessiononly"), ignore_label);
}
else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
{
setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label);
}
setCheckBoxes(HPAD, VPAD);
// *TODO: check necessity of this code
//gFloaterView->adjustToFitScreen(this, FALSE);
@ -394,46 +380,6 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
LLTransientFloaterMgr::GLOBAL, this);
}
bool LLToastAlertPanel::setCheckBox( const std::string& check_title, const std::string& check_control )
{
mCheck = LLUICtrlFactory::getInstance()->createFromFile<LLCheckBoxCtrl>("alert_check_box.xml", this, LLPanel::child_registry_t::instance());
if(!mCheck)
{
return false;
}
const LLFontGL* font = mCheck->getFont();
const S32 LINE_HEIGHT = font->getLineHeight();
std::vector<std::string> lines;
boost::split(lines, check_title, boost::is_any_of("\n"));
// Extend dialog for "check next time"
S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * HPAD;
S32 check_width = S32(font->getWidth(lines[0]) + 0.99f) + 16; // use width of the first line
max_msg_width = llmax(max_msg_width, check_width);
S32 dialog_width = max_msg_width + 2 * HPAD;
S32 dialog_height = LLToastPanel::getRect().getHeight();
dialog_height += LINE_HEIGHT * lines.size();
dialog_height += LINE_HEIGHT / 2;
LLToastPanel::reshape( dialog_width, dialog_height, FALSE );
S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2;
// set check_box's attributes
LLRect check_rect;
mCheck->setRect(check_rect.setOriginAndSize(msg_x, VPAD+BTN_HEIGHT+LINE_HEIGHT/2, max_msg_width, LINE_HEIGHT*lines.size()));
mCheck->setLabel(check_title);
mCheck->setCommitCallback(boost::bind(&LLToastAlertPanel::onClickIgnore, this, _1));
LLToastPanel::addChild(mCheck);
return true;
}
void LLToastAlertPanel::setVisible( BOOL visible )
{
// only make the "ding" sound if it's newly visible
@ -584,16 +530,3 @@ void LLToastAlertPanel::onButtonPressed( const LLSD& data, S32 button )
mNotification->respond(response); // new notification reponse
}
void LLToastAlertPanel::onClickIgnore(LLUICtrl* ctrl)
{
// checkbox sometimes means "hide and do the default" and
// other times means "warn me again". Yuck. JC
BOOL check = ctrl->getValue().asBoolean();
if (mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
{
// question was "show again" so invert value to get "ignore"
check = !check;
}
mNotification->setIgnored(check);
}

View File

@ -46,7 +46,7 @@ class LLLineEditor;
*/
class LLToastAlertPanel
: public LLToastPanel
: public LLCheckBoxToastPanel
{
LOG_CLASS(LLToastAlertPanel);
public:
@ -75,13 +75,11 @@ public:
virtual void draw();
virtual void setVisible( BOOL visible );
bool setCheckBox( const std::string&, const std::string& );
void setCaution(BOOL val = TRUE) { mCaution = val; }
// If mUnique==TRUE only one copy of this message should exist
void setUnique(BOOL val = TRUE) { mUnique = val; }
void setEditTextArgs(const LLSD& edit_args);
void onClickIgnore(LLUICtrl* ctrl);
void onButtonPressed(const LLSD& data, S32 button);
private:
@ -106,7 +104,6 @@ private:
std::vector<ButtonData> mButtonData;
S32 mDefaultOption;
LLCheckBoxCtrl* mCheck;
BOOL mCaution;
BOOL mUnique;
LLUIString mLabel;

View File

@ -33,6 +33,7 @@
// library includes
#include "lldbstrings.h"
#include "llcheckboxctrl.h"
#include "lllslconstants.h"
#include "llnotifications.h"
#include "lluiconstants.h"
@ -59,7 +60,7 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal;
LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images)
: LLToastPanel(notification),
: LLCheckBoxToastPanel(notification),
LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>(notification->getID())
{
init(rect, show_images);
@ -434,6 +435,11 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
//.xml file intially makes info panel only follow left/right/top. This is so that when control buttons are added the info panel
//can shift upward making room for the buttons inside mControlPanel. After the buttons are added, the info panel can then be set to follow 'all'.
mInfoPanel->setFollowsAll();
// Add checkboxes if nessesary.
setCheckBoxes(HPAD * 3, VPAD * 4, mInfoPanel);
// Snap to message, then to checkbox if present
// <FS:Ansariel> FIRE-17100: Customizable number of rows in a script dialog
//snapToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH);
if (mIsScriptDialog)
@ -447,6 +453,11 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
snapToMessageHeight(mTextBox, LLToastPanel::MAX_TEXT_LENGTH);
}
// </FS:Ansariel>
if (mCheck)
{
S32 new_panel_height = mCheck->getRect().getHeight() + getRect().getHeight();
reshape(getRect().getWidth(), new_panel_height);
}
// reshape the panel to its previous size
if (current_rect.notEmpty())

View File

@ -47,7 +47,7 @@ class LLNotificationForm;
* @deprecated this class will be removed after all toast panel types are
* implemented in separate classes.
*/
class LLToastNotifyPanel: public LLToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>
class LLToastNotifyPanel: public LLCheckBoxToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID, LLInstanceTrackerReplaceOnCollision>
{
public:
/**

View File

@ -27,6 +27,7 @@
#include "llviewerprecompiledheaders.h"
#include "lldbstrings.h"
#include "llcheckboxctrl.h"
#include "llpanelgenerictip.h"
#include "llpanelonlinestatus.h"
#include "llnotifications.h"
@ -34,6 +35,8 @@
#include "lltoastpanel.h"
#include "lltoastscriptquestion.h"
#include <boost/algorithm/string.hpp>
//static
const S32 LLToastPanel::MIN_PANEL_HEIGHT = 40; // VPAD(4)*2 + ICON_HEIGHT(32)
// 'magic numbers', consider initializing (512+20) part from xml/notifications
@ -151,3 +154,93 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification(
return res;
}
LLCheckBoxToastPanel::LLCheckBoxToastPanel(const LLNotificationPtr& p_ntf)
: LLToastPanel(p_ntf),
mCheck(NULL)
{
}
void LLCheckBoxToastPanel::setCheckBoxes(const S32 &h_pad, const S32 &v_pad, LLView *parent_view)
{
std::string ignore_label;
LLNotificationFormPtr form = mNotification->getForm();
if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE)
{
setCheckBox(LLNotifications::instance().getGlobalString("skipnexttime"), ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
}
if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE_SESSION_ONLY)
{
setCheckBox(LLNotifications::instance().getGlobalString("skipnexttimesessiononly"), ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
}
else if (form->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
{
setCheckBox(LLNotifications::instance().getGlobalString("alwayschoose"), ignore_label, boost::bind(&LLCheckBoxToastPanel::onCommitCheckbox, this, _1), h_pad, v_pad, parent_view);
}
}
bool LLCheckBoxToastPanel::setCheckBox(const std::string& check_title,
const std::string& check_control,
const commit_signal_t::slot_type& cb,
const S32 &h_pad,
const S32 &v_pad,
LLView *parent_view)
{
mCheck = LLUICtrlFactory::getInstance()->createFromFile<LLCheckBoxCtrl>("alert_check_box.xml", this, LLPanel::child_registry_t::instance());
if (!mCheck)
{
return false;
}
const LLFontGL* font = mCheck->getFont();
const S32 LINE_HEIGHT = font->getLineHeight();
std::vector<std::string> lines;
boost::split(lines, check_title, boost::is_any_of("\n"));
// Extend dialog for "check next time"
S32 max_msg_width = LLToastPanel::getRect().getWidth() - 2 * h_pad;
S32 check_width = S32(font->getWidth(lines[0]) + 0.99f) + 16; // use width of the first line
max_msg_width = llmax(max_msg_width, check_width);
S32 dialog_width = max_msg_width + 2 * h_pad;
S32 dialog_height = LLToastPanel::getRect().getHeight();
dialog_height += LINE_HEIGHT * lines.size();
dialog_height += LINE_HEIGHT / 2;
LLToastPanel::reshape(dialog_width, dialog_height, FALSE);
S32 msg_x = (LLToastPanel::getRect().getWidth() - max_msg_width) / 2;
// set check_box's attributes
LLRect check_rect;
mCheck->setRect(check_rect.setOriginAndSize(msg_x, v_pad + BTN_HEIGHT + LINE_HEIGHT / 2, max_msg_width, LINE_HEIGHT*lines.size()));
mCheck->setLabel(check_title);
mCheck->setCommitCallback(cb);
if (parent_view)
{
// assume that width and height autoadjusts to toast
parent_view->addChild(mCheck);
}
else
{
LLToastPanel::addChild(mCheck);
}
return true;
}
void LLCheckBoxToastPanel::onCommitCheckbox(LLUICtrl* ctrl)
{
BOOL check = ctrl->getValue().asBoolean();
if (mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
{
// question was "show again" so invert value to get "ignore"
check = !check;
}
mNotification->setIgnored(check);
}

View File

@ -64,4 +64,23 @@ protected:
S32 computeSnappedToMessageHeight(LLTextBase* message, S32 maxLineCount);
};
class LLCheckBoxCtrl;
// Wrapper with support for 'don't ask again' checkbox
class LLCheckBoxToastPanel : public LLToastPanel
{
public:
LLCheckBoxToastPanel(const LLNotificationPtr& p_ntf);
virtual ~LLCheckBoxToastPanel() {};
// set checkboxes acording to defaults from form
void setCheckBoxes(const S32 &h_pad, const S32 &v_pad, LLView *parent_view = NULL);
// set single checkbox
bool setCheckBox(const std::string&, const std::string&, const commit_signal_t::slot_type& cb, const S32 &h_pad, const S32 &v_pad, LLView *parent_view = NULL);
protected:
void onCommitCheckbox(LLUICtrl* ctrl);
LLCheckBoxCtrl* mCheck;
};
#endif /* LL_TOASTPANEL_H */

View File

@ -154,6 +154,9 @@ const F32 PHYSICS_TIMESTEP = 1.f / 45.f;
const U32 MAX_INV_FILE_READ_FAILS = 25;
const S32 MAX_OBJECT_BINARY_DATA_SIZE = 60 + 16;
const F64 INVENTORY_UPDATE_WAIT_TIME_DESYNC = 5; // seconds
const F64 INVENTORY_UPDATE_WAIT_TIME_OUTDATED = 1;
static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object");
// static
@ -3058,6 +3061,8 @@ void LLViewerObject::fetchInventoryFromServer()
if (!isInventoryPending())
{
delete mInventory;
// Results in processTaskInv
LLMessageSystem* msg = gMessageSystem;
msg->newMessageFast(_PREHASH_RequestTaskInventory);
msg->nextBlockFast(_PREHASH_AgentData);
@ -3067,11 +3072,44 @@ void LLViewerObject::fetchInventoryFromServer()
msg->addU32Fast(_PREHASH_LocalID, mLocalID);
msg->sendReliable(mRegionp->getHost());
// this will get reset by dirtyInventory or doInventoryCallback
// This will get reset by doInventoryCallback or processTaskInv
mInvRequestState = INVENTORY_REQUEST_PENDING;
}
}
void LLViewerObject::fetchInventoryDelayed(const F64 &time_seconds)
{
// unless already waiting, drop previous request and shedule an update
if (mInvRequestState != INVENTORY_REQUEST_WAIT)
{
if (mInvRequestXFerId != 0)
{
// abort download.
gXferManager->abortRequestById(mInvRequestXFerId, -1);
mInvRequestXFerId = 0;
}
mInvRequestState = INVENTORY_REQUEST_WAIT; // affects isInventoryPending()
LLCoros::instance().launch("LLViewerObject::fetchInventoryDelayedCoro()",
boost::bind(&LLViewerObject::fetchInventoryDelayedCoro, mID, time_seconds));
}
}
//static
void LLViewerObject::fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds)
{
llcoro::suspendUntilTimeout(time_seconds);
LLViewerObject *obj = gObjectList.findObject(task_inv);
if (obj)
{
// Might be good idea to prolong delay here in case expected serial changed.
// As it is, it will get a response with obsolete serial and will delay again.
// drop waiting state to unlock isInventoryPending()
obj->mInvRequestState = INVENTORY_REQUEST_STOPPED;
obj->fetchInventoryFromServer();
}
}
LLControlAvatar *LLViewerObject::getControlAvatar()
{
return getRootEdit()->mControlAvatar.get();
@ -3258,30 +3296,32 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
// we can receive multiple task updates simultaneously, make sure we will not rewrite newer with older update
msg->getS16Fast(_PREHASH_InventoryData, _PREHASH_Serial, ft->mSerial);
if (ft->mSerial == object->mInventorySerialNum)
if (ft->mSerial == object->mInventorySerialNum
&& ft->mSerial < object->mExpectedInventorySerialNum)
{
// Loop Protection.
// We received same serial twice.
// Viewer did some changes to inventory that couldn't be saved server side
// or something went wrong to cause serial to be out of sync
// or something went wrong to cause serial to be out of sync.
// Drop xfer and restart after some time, assign server's value as expected
LL_WARNS() << "Task inventory serial might be out of sync, server serial: " << ft->mSerial << " client expected serial: " << object->mExpectedInventorySerialNum << LL_ENDL;
object->mExpectedInventorySerialNum = ft->mSerial;
object->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_DESYNC);
}
if (ft->mSerial < object->mExpectedInventorySerialNum)
else if (ft->mSerial < object->mExpectedInventorySerialNum)
{
// out of date message, record to current serial for loop protection, but do not load it
// just drop xfer to restart on idle
// Out of date message, record to current serial for loop protection, but do not load it
// Drop xfer and restart after some time
if (ft->mSerial < object->mInventorySerialNum)
{
LL_WARNS() << "Somehow task serial decreased, out of order packet?" << LL_ENDL;
LL_WARNS() << "Task serial decreased. Potentially out of order packet or desync." << LL_ENDL;
}
object->mInventorySerialNum = ft->mSerial;
object->mInvRequestXFerId = 0;
object->mInvRequestState = INVENTORY_REQUEST_STOPPED;
object->fetchInventoryDelayed(INVENTORY_UPDATE_WAIT_TIME_OUTDATED);
}
else if (ft->mSerial >= object->mExpectedInventorySerialNum)
{
// We received version we expected or newer. Load it.
object->mInventorySerialNum = ft->mSerial;
object->mExpectedInventorySerialNum = ft->mSerial;

View File

@ -639,9 +639,13 @@ private:
static void initObjectDataMap();
// forms task inventory request if none are pending
// forms task inventory request if none are pending, marks request as pending
void fetchInventoryFromServer();
// forms task inventory request after some time passed, marks request as pending
void fetchInventoryDelayed(const F64 &time_seconds);
static void fetchInventoryDelayedCoro(const LLUUID task_inv, const F64 time_seconds);
public:
//
// Viewer-side only types - use the LL_PCODE_APP mask.
@ -828,8 +832,9 @@ protected:
enum EInventoryRequestState
{
INVENTORY_REQUEST_STOPPED,
INVENTORY_REQUEST_PENDING,
INVENTORY_XFER
INVENTORY_REQUEST_WAIT, // delay before requesting
INVENTORY_REQUEST_PENDING, // just did fetchInventoryFromServer()
INVENTORY_XFER // processed response from 'fetch', now doing an xfer
};
EInventoryRequestState mInvRequestState;
U64 mInvRequestXFerId;

View File

@ -365,16 +365,19 @@ void update_statistics()
record(LLStatViewer::REBUILD_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Sort Draw State")));
record(LLStatViewer::RENDER_STACKTIME, last_frame_recording.getSum(*stat_type_t::getInstance("Render Geometry")));
LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
if (cdp)
if (gAgent.getRegion() && isAgentAvatarValid())
{
sample(LLStatViewer::SIM_PING, F64Milliseconds (cdp->getPingDelay()));
gAvgSimPing = ((gAvgSimPing * gSimPingCount) + cdp->getPingDelay()) / (gSimPingCount + 1);
gSimPingCount++;
}
else
{
sample(LLStatViewer::SIM_PING, U32Seconds(10));
LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
if (cdp)
{
sample(LLStatViewer::SIM_PING, F64Milliseconds(cdp->getPingDelay()));
gAvgSimPing = ((gAvgSimPing * gSimPingCount) + cdp->getPingDelay()) / (gSimPingCount + 1);
gSimPingCount++;
}
else
{
sample(LLStatViewer::SIM_PING, U32Seconds(10));
}
}
if (LLViewerStats::instance().getRecording().getSum(LLStatViewer::FPS))

View File

@ -8876,8 +8876,7 @@ void LLPipeline::renderDeferredLighting()
}
const LLViewerObject *vobj = drawablep->getVObj();
if(vobj && vobj->getAvatar()
&& (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList())
if((vobj && vobj->getAvatar() && (vobj->getAvatar()->isTooComplex() || vobj->getAvatar()->isInMuteList()))
|| (vobj && dist_vec(vobj->getPosition(), LLViewerCamera::getInstance()->getOrigin()) > RenderFarClip))
{
continue;

View File

@ -6471,6 +6471,20 @@ Are you sure you want to permanently delete the contents of your Lost And Found?
yestext="Yes"/>
</notification>
<notification
icon="alertmodal.tga"
name="ConfirmReplaceLink"
type="alertmodal">
You're about to replace '[TYPE]' body part link with the item which doesn't match the type.
Are you sure you want to proceed?
<tag>confirm</tag>
<usetemplate
ignoretext="Confirm before I replace link"
name="okcancelignore"
notext="No"
yestext="Yes"/>
</notification>
<notification
icon="alertmodal.tga"
name="CopySLURL"

View File

@ -60,7 +60,7 @@ no el objeto.
</text>
<button label="Comprar ahora" name="buy_btn"/>
<button label="Cancelar" name="cancel_btn"/>
<text left="5" name="info_cannot_buy" right="-5">
<text name="info_cannot_buy" left="150" font="SansSerifBig">
No se pudo hacer la compra
</text>
<button label="Ir a la web" name="error_web"/>

View File

@ -1,25 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<floater title="Acheter des L$" name="buy currency">
<floater.string name="buy_currency">Acheter [LINDENS] L$ pour environ [LOCALAMOUNT]</floater.string>
<text name="info_need_more">Vous avez besoin de plus de L$</text>
<text name="contacting">Contact du LindeX en cours...</text>
<text name="info_buying">Acheter des L$</text>
<text name="balance_label">Je possède</text>
<text name="balance_amount">[AMT] L$</text>
<text name="currency_action">Je veux acheter</text>
<text name="currency_label">L$</text>
<text name="buying_label">Pour</text>
<text name="currency_est">environ [LOCALAMOUNT]</text>
<text name="getting_data">Estimation en cours...</text>
<text name="buy_action">[ACTION]</text>
<text name="total_label">Mon nouveau solde sera de</text>
<text name="total_amount">[AMT] L$</text>
<text name="currency_links">[http://www.secondlife.com/my/account/payment_method_management.php méthode de payement] | [http://www.secondlife.com/my/account/currency.php devise]</text>
<text name="exchange_rate_note">Ressaisissez le montant pour voir le taux de change actuel</text>
<text name="purchase_warning_repurchase">Confirmer cet achat n'achète que des L$, pas l'objet.</text>
<text name="purchase_warning_notenough">Vous n'achetez pas assez de L$. Veuillez augmenter le montant.</text>
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<floater name="buy currency" title="ACHETER DES L$">
<floater.string name="buy_currency">
Achetez [LINDENS] L$ pour environ [LOCALAMOUNT]
</floater.string>
<text left="5" name="info_need_more" right="-5">
Plus de L$ sont requis
</text>
<text name="contacting">
En train de contacter
le Lindex...
</text>
<text left="5" name="info_buying">
Acheter des L$
</text>
<text name="balance_label">
J&apos;ai
</text>
<text name="balance_amount">
[AMT] L$
</text>
<text name="currency_action">
Je veux acheter
</text>
<text left="308" name="currency_label">
L$
</text>
<line_editor label="L$" left_pad="-85" name="currency_amt" width="65">
1234
</line_editor>
<text name="buying_label">
Pour
</text>
<text left_delta="68" name="currency_est" width="138">
environ [LOCALAMOUNT]
</text>
<text name="getting_data" width="138">
Estimation en cours...
</text>
<text name="buy_action">
[ACTION]
</text>
<text name="total_label">
Mon nouveau solde sera de
</text>
<text name="total_amount">
[AMT] L$
</text>
<text name="currency_links">
[http://www.secondlife.com/my/account/payment_method_management.php mode de paiement] | [http://www.secondlife.com/my/account/currency.php devise]
</text>
<text name="exchange_rate_note">
Saisissez à nouveau le montant pour voir le taux de change actuel.
</text>
<text name="purchase_warning_repurchase">
Confirmer cet achat n&apos;achète que des L$, pas l&apos;objet.
</text>
<text bottom_delta="16" name="purchase_warning_notenough">
Vous n&apos;achetez pas assez de L$. Veuillez augmenter le montant.
</text>
<button label="Acheter" name="buy_btn"/>
<button label="Annuler" name="cancel_btn"/>
<text name="info_cannot_buy">Achat impossible</text>
<button label="Continuer sur Internet" name="error_web"/>
<text name="info_cannot_buy" left="160" width="200">
Achat impossible
</text>
<button label="Accéder au Web" name="error_web"/>
</floater>

View File

@ -51,7 +51,7 @@ l&apos;oggetto.
</text>
<button label="Acquista" name="buy_btn"/>
<button label="Annulla" name="cancel_btn"/>
<text left="5" name="info_cannot_buy" right="-5">
<text name="info_cannot_buy" left="160" font="SansSerifBig">
Impossibile acquistare
</text>
<button label="Continua sul Web" name="error_web"/>