Merge viewer-neko
commit
c62ef0981b
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"/>
|
||||
|
|
|
|||
|
|
@ -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'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'achète que des L$, pas l'objet.
|
||||
</text>
|
||||
<text bottom_delta="16" name="purchase_warning_notenough">
|
||||
Vous n'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>
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ l'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"/>
|
||||
|
|
|
|||
Loading…
Reference in New Issue