13041 lines
412 KiB
C++
13041 lines
412 KiB
C++
/**
|
|
* @file llviewermenu.cpp
|
|
* @brief Builds menus out of items.
|
|
*
|
|
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
|
|
* Second Life Viewer Source Code
|
|
* Copyright (C) 2014, Linden Research, Inc.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation;
|
|
* version 2.1 of the License only.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*
|
|
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
|
|
* $/LicenseInfo$
|
|
*/
|
|
|
|
#include "llviewerprecompiledheaders.h"
|
|
|
|
#ifdef INCLUDE_VLD
|
|
#define VLD_FORCE_ENABLE 1
|
|
#include "vld.h"
|
|
#endif
|
|
|
|
#include "llviewermenu.h"
|
|
|
|
// linden library includes
|
|
#include "llavatarnamecache.h" // IDEVO (I Are Not Men!)
|
|
#include "llcombobox.h"
|
|
#include "llcoros.h"
|
|
#include "llfloaterreg.h"
|
|
#include "llfloatersidepanelcontainer.h"
|
|
#include "llinventorypanel.h"
|
|
#include "llnotifications.h"
|
|
#include "llnotificationsutil.h"
|
|
#include "llviewereventrecorder.h"
|
|
#include "v4coloru.h"
|
|
|
|
// newview includes
|
|
#include "llagent.h"
|
|
#include "llagentaccess.h"
|
|
#include "llagentbenefits.h"
|
|
#include "llagentcamera.h"
|
|
#include "llagentui.h"
|
|
#include "llagentwearables.h"
|
|
#include "llagentpilot.h"
|
|
// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
|
|
#include "llattachmentsmgr.h"
|
|
// [/SL:KB]
|
|
#include "llcompilequeue.h"
|
|
#include "llconsole.h"
|
|
#include "lldebugview.h"
|
|
#include "lldiskcache.h"
|
|
#include "llenvironment.h"
|
|
#include "llfilepicker.h"
|
|
#include "llfirstuse.h"
|
|
#include "llfloaterabout.h"
|
|
#include "llfloaterbuy.h"
|
|
#include "llfloaterbuycontents.h"
|
|
#include "llbuycurrencyhtml.h"
|
|
#include "llfloatergodtools.h"
|
|
#include "llfloaterimcontainer.h"
|
|
#include "llfloaterland.h"
|
|
#include "llfloaterimnearbychat.h"
|
|
#include "llfloaterlandholdings.h"
|
|
#include "llfloaterpathfindingcharacters.h"
|
|
#include "llfloaterpathfindinglinksets.h"
|
|
#include "llfloaterpay.h"
|
|
#include "llfloaterreporter.h"
|
|
#include "llfloatersearch.h"
|
|
#include "llfloaterscriptdebug.h"
|
|
#include "llfloatersnapshot.h"
|
|
#include "llfloatertools.h"
|
|
#include "llfloaterworldmap.h"
|
|
#include "llfloaterbuildoptions.h"
|
|
#include "llavataractions.h"
|
|
#include "lllandmarkactions.h"
|
|
#include "llgroupmgr.h"
|
|
#include "lltooltip.h"
|
|
#include "lltoolface.h"
|
|
#include "llhints.h"
|
|
#include "llhudeffecttrail.h"
|
|
#include "llhudmanager.h"
|
|
#include "llimview.h"
|
|
#include "llinventorybridge.h"
|
|
#include "llinventorydefines.h"
|
|
#include "llinventoryfunctions.h"
|
|
#include "llpanellogin.h"
|
|
#include "llpanelblockedlist.h"
|
|
#include "llpanelmaininventory.h"
|
|
#include "llmarketplacefunctions.h"
|
|
#include "llmaterialeditor.h"
|
|
#include "llmenuoptionpathfindingrebakenavmesh.h"
|
|
#include "llmoveview.h"
|
|
#include "llnavigationbar.h"
|
|
#include "llparcel.h"
|
|
#include "llrootview.h"
|
|
#include "llsceneview.h"
|
|
#include "llscenemonitor.h"
|
|
#include "llselectmgr.h"
|
|
#include "llsidepanelappearance.h"
|
|
#include "llspellcheckmenuhandler.h"
|
|
#include "llstatusbar.h"
|
|
#include "llterrainpaintmap.h"
|
|
#include "lltextureview.h"
|
|
#include "lltoolbarview.h"
|
|
#include "lltoolcomp.h"
|
|
#include "lltoolmgr.h"
|
|
#include "lltoolpie.h"
|
|
#include "lltoolselectland.h"
|
|
#include "lltrans.h"
|
|
#include "llviewerdisplay.h" //for gWindowResized
|
|
#include "llviewergenericmessage.h"
|
|
#include "llviewerhelp.h"
|
|
#include "llviewermenufile.h" // init_menu_file()
|
|
#include "llviewermessage.h"
|
|
#include "llviewernetwork.h"
|
|
#include "llviewerobjectlist.h"
|
|
#include "llviewerparcelmgr.h"
|
|
#include "llviewerstats.h"
|
|
#include "llviewerstatsrecorder.h"
|
|
#include "llvlcomposition.h"
|
|
#include "llvoavatarself.h"
|
|
#include "llvoicevivox.h"
|
|
#include "llworld.h"
|
|
#include "llworldmap.h"
|
|
#include "pipeline.h"
|
|
#include "llviewerjoystick.h"
|
|
#include "llfloatercamera.h"
|
|
#include "lluilistener.h"
|
|
#include "llappearancemgr.h"
|
|
#include "lltrans.h"
|
|
#include "lltoolgrab.h"
|
|
#include "llwindow.h"
|
|
#include "llpathfindingmanager.h"
|
|
#include "llstartup.h"
|
|
#include "boost/unordered_map.hpp"
|
|
#include <boost/regex.hpp>
|
|
#include <boost/algorithm/string.hpp>
|
|
#include <boost/json.hpp>
|
|
#include "llcleanup.h"
|
|
#include "llviewershadermgr.h"
|
|
#include "gltfscenemanager.h"
|
|
#include "gltf/asset.h"
|
|
// [RLVa:KB] - Checked: 2011-05-22 (RLVa-1.3.1a)
|
|
#include "fsavatarrenderpersistence.h"
|
|
#include "rlvactions.h"
|
|
#include "rlvhandler.h"
|
|
#include "rlvlocks.h"
|
|
// [/RLVa:KB]
|
|
|
|
// Firestorm includes
|
|
#include "fsassetblacklist.h"
|
|
#include "fsdata.h"
|
|
#include "fslslbridge.h"
|
|
#include "fscommon.h"
|
|
#include "fsfloaterexport.h"
|
|
#include "fsfloatercontacts.h"
|
|
#include "fsfloaterplacedetails.h"
|
|
#include "fspose.h"
|
|
#include "lfsimfeaturehandler.h"
|
|
#include "llavatarpropertiesprocessor.h"
|
|
#include "llcheckboxctrl.h"
|
|
#include "llfloatergridstatus.h"
|
|
#include "llfloaterpreference.h"
|
|
#include "llkeyconflict.h"
|
|
#include "lllogininstance.h"
|
|
#include "llscenemonitor.h"
|
|
#include "llsdserialize.h"
|
|
#include "lltexturecache.h"
|
|
#include "llvovolume.h"
|
|
#include "particleeditor.h"
|
|
#include "permissionstracker.h"
|
|
|
|
using namespace LLAvatarAppearanceDefines;
|
|
|
|
typedef LLPointer<LLViewerObject> LLViewerObjectPtr;
|
|
|
|
static boost::unordered_map<std::string, LLStringExplicit> sDefaultItemLabels;
|
|
|
|
LLVOAvatar* find_avatar_from_object(LLViewerObject* object);
|
|
LLVOAvatar* find_avatar_from_object(const LLUUID& object_id);
|
|
|
|
void handle_test_load_url();
|
|
|
|
//
|
|
// Evil hackish imported globals
|
|
|
|
extern bool gDebugClicks;
|
|
extern bool gDebugWindowProc;
|
|
extern bool gShaderProfileFrame;
|
|
|
|
//
|
|
// Globals
|
|
//
|
|
|
|
LLMenuBarGL *gMenuBarView = NULL;
|
|
LLViewerMenuHolderGL *gMenuHolder = NULL;
|
|
LLMenuGL *gPopupMenuView = NULL;
|
|
LLMenuGL *gEditMenu = NULL;
|
|
LLMenuBarGL *gLoginMenuBarView = NULL;
|
|
|
|
// Context menus
|
|
LLContextMenu *gMenuAvatarSelf = NULL;
|
|
LLContextMenu *gMenuAvatarOther = NULL;
|
|
LLContextMenu *gMenuObject = NULL;
|
|
LLContextMenu *gMenuAttachmentSelf = NULL;
|
|
LLContextMenu *gMenuAttachmentOther = NULL;
|
|
LLContextMenu *gMenuLand = NULL;
|
|
LLContextMenu *gMenuMuteParticle = NULL;
|
|
|
|
// <FS:Zi> Pie menu
|
|
// Pie menus
|
|
PieMenu *gPieMenuAvatarSelf = NULL;
|
|
PieMenu *gPieMenuAvatarOther = NULL;
|
|
PieMenu *gPieMenuObject = NULL;
|
|
PieMenu *gPieMenuAttachmentSelf = NULL;
|
|
PieMenu *gPieMenuAttachmentOther = NULL;
|
|
PieMenu *gPieMenuLand = NULL;
|
|
PieMenu *gPieMenuMuteParticle = NULL;
|
|
// <FS:Zi> Pie menu
|
|
|
|
// <FS:Ansariel> FIRE-7893: Detach function on inspect self toast without function
|
|
LLToggleableMenu *gMenuInspectSelf = NULL;
|
|
LLContextMenu *gInspectSelfDetachScreenMenu = NULL;
|
|
LLContextMenu *gInspectSelfDetachMenu = NULL;
|
|
// </FS:Ansariel>
|
|
|
|
const std::string SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents");
|
|
|
|
LLMenuGL* gAttachSubMenu = NULL;
|
|
LLMenuGL* gDetachSubMenu = NULL;
|
|
LLMenuGL* gTakeOffClothes = NULL;
|
|
LLMenuGL* gDetachAvatarMenu = NULL;
|
|
LLMenuGL* gDetachHUDAvatarMenu = NULL;
|
|
LLContextMenu* gAttachScreenPieMenu = NULL;
|
|
LLContextMenu* gAttachPieMenu = NULL;
|
|
LLContextMenu* gAttachBodyPartPieMenus[9];
|
|
LLContextMenu* gDetachPieMenu = NULL;
|
|
LLContextMenu* gDetachScreenPieMenu = NULL;
|
|
LLContextMenu* gDetachAttSelfMenu = NULL;
|
|
LLContextMenu* gDetachHUDAttSelfMenu = NULL;
|
|
LLContextMenu* gDetachBodyPartPieMenus[9];
|
|
|
|
// <FS:Zi> Pie menu
|
|
PieMenu* gPieAttachScreenMenu = NULL;
|
|
PieMenu* gPieAttachMenu = NULL;
|
|
PieMenu* gPieAttachBodyPartMenus[PIE_MAX_SLICES];
|
|
PieMenu* gPieDetachMenu = NULL;
|
|
PieMenu* gPieDetachScreenMenu = NULL;
|
|
PieMenu* gPieDetachBodyPartMenus[PIE_MAX_SLICES];
|
|
// <FS:Zi> Pie menu
|
|
|
|
LLMenuItemCallGL* gAutorespondMenu = NULL;
|
|
LLMenuItemCallGL* gAutorespondNonFriendsMenu = NULL;
|
|
//
|
|
// Local prototypes
|
|
|
|
// File Menu
|
|
void handle_compress_image();
|
|
void handle_compress_file_test();
|
|
|
|
|
|
// Edit menu
|
|
void handle_dump_group_info();
|
|
void handle_dump_capabilities_info();
|
|
|
|
// Advanced->Consoles menu
|
|
void handle_region_dump_settings();
|
|
void handle_region_dump_temp_asset_data();
|
|
void handle_region_clear_temp_asset_data();
|
|
|
|
// Object pie menu
|
|
bool sitting_on_selection();
|
|
|
|
// buy and take alias into the same UI positions, so these
|
|
// declarations handle this mess.
|
|
bool is_selection_buy_not_take();
|
|
S32 selection_price();
|
|
bool enable_take();
|
|
void handle_object_show_inspector();
|
|
void handle_avatar_show_inspector();
|
|
bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection_handle);
|
|
bool confirm_take_separate(const LLSD ¬ification, const LLSD &response, LLObjectSelectionHandle selection_handle);
|
|
|
|
void handle_buy_object(LLSaleInfo sale_info);
|
|
void handle_buy_contents(LLSaleInfo sale_info);
|
|
|
|
// Land pie menu
|
|
void near_sit_down_point(bool success, void*);
|
|
|
|
// Debug menu
|
|
void handle_visual_leak_detector_toggle();
|
|
void handle_rebake_textures();
|
|
bool check_admin_override();
|
|
void handle_admin_override_toggle();
|
|
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
|
|
void handle_toggle_hacked_godmode();
|
|
bool check_toggle_hacked_godmode();
|
|
bool enable_toggle_hacked_godmode();
|
|
#endif
|
|
|
|
void toggle_show_xui_names();
|
|
bool check_show_xui_names();
|
|
|
|
// Debug UI
|
|
|
|
void handle_buy_currency_test();
|
|
void handle_save_to_xml(void*);
|
|
void handle_load_from_xml(void*);
|
|
|
|
void handle_god_mode();
|
|
|
|
// God menu
|
|
void handle_leave_god_mode();
|
|
|
|
|
|
void handle_reset_view();
|
|
|
|
void handle_object_owner_self();
|
|
void handle_object_owner_permissive();
|
|
void handle_object_lock();
|
|
void handle_object_asset_ids();
|
|
void force_take_copy();
|
|
|
|
void handle_force_parcel_owner_to_me();
|
|
void handle_force_parcel_to_content();
|
|
void handle_claim_public_land();
|
|
|
|
void handle_god_request_avatar_geometry(); // Hack for easy testing of new avatar geometry
|
|
void reload_vertex_shader();
|
|
void handle_disconnect_viewer();
|
|
|
|
void force_error_breakpoint();
|
|
void force_error_llerror();
|
|
void force_error_llerror_msg();
|
|
void force_error_bad_memory_access();
|
|
void force_error_infinite_loop();
|
|
void force_error_software_exception();
|
|
void force_error_os_exception();
|
|
void force_error_driver_crash();
|
|
void force_error_coroutine_crash();
|
|
void force_error_thread_crash();
|
|
|
|
void handle_force_delete();
|
|
void print_object_info();
|
|
void print_agent_nvpairs();
|
|
void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExtStat ext_status);
|
|
void dump_select_mgr();
|
|
|
|
void dump_inventory();
|
|
void toggle_visibility(LLView* viewp);
|
|
bool get_visibility(LLView* viewp);
|
|
|
|
// Avatar Pie menu
|
|
void request_friendship(const LLUUID& agent_id);
|
|
|
|
// Tools menu
|
|
void handle_selected_texture_info();
|
|
void handle_selected_material_info();
|
|
|
|
void handle_dump_followcam();
|
|
void handle_viewer_enable_message_log();
|
|
void handle_viewer_disable_message_log();
|
|
|
|
bool enable_buy_land();
|
|
|
|
// Help menu
|
|
|
|
void handle_test_male();
|
|
void handle_test_female();
|
|
void handle_dump_attachments();
|
|
void handle_dump_avatar_local_textures();
|
|
void handle_debug_avatar_textures();
|
|
void handle_grab_baked_texture(EBakedTextureIndex baked_tex_index);
|
|
bool enable_grab_baked_texture(EBakedTextureIndex baked_tex_index);
|
|
void handle_dump_region_object_cache();
|
|
void handle_reset_interest_lists();
|
|
|
|
bool enable_save_into_task_inventory();
|
|
|
|
bool enable_detach(const LLSD& = LLSD());
|
|
void menu_toggle_attached_lights();
|
|
void menu_toggle_attached_particles();
|
|
|
|
void avatar_tex_refresh(LLVOAvatar* avatar); // <FS:CR> FIRE-11800
|
|
|
|
class LLMenuParcelObserver : public LLParcelObserver
|
|
{
|
|
public:
|
|
LLMenuParcelObserver();
|
|
~LLMenuParcelObserver();
|
|
void changed() override;
|
|
private:
|
|
LLHandle<LLUICtrl> mLandBuyHandle;
|
|
LLHandle<LLUICtrl> mLandBuyPassHandle;
|
|
};
|
|
|
|
static LLMenuParcelObserver* gMenuParcelObserver = NULL;
|
|
|
|
static LLUIListener sUIListener;
|
|
|
|
LLMenuParcelObserver::LLMenuParcelObserver()
|
|
{
|
|
mLandBuyHandle = gMenuLand->getChild<LLMenuItemCallGL>("Land Buy")->getHandle();
|
|
mLandBuyPassHandle = gMenuLand->getChild<LLMenuItemCallGL>("Land Buy Pass")->getHandle();
|
|
LLViewerParcelMgr::getInstance()->addObserver(this);
|
|
}
|
|
|
|
LLMenuParcelObserver::~LLMenuParcelObserver()
|
|
{
|
|
LLViewerParcelMgr::getInstance()->removeObserver(this);
|
|
}
|
|
|
|
void LLMenuParcelObserver::changed()
|
|
{
|
|
LLParcel *parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
|
|
if (gMenuLand && parcel)
|
|
{
|
|
// <FS:Ansariel> FIRE-4454: Cache controls because of performance reasons
|
|
//if (!mLandBuyPassHandle.isDead())
|
|
//{
|
|
// LLParcel *parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
|
|
// static_cast<LLMenuItemCallGL*>(mLandBuyPassHandle.get())->setEnabled(LLPanelLandGeneral::enableBuyPass(nullptr) && parcel->getOwnerID() != gAgentID);
|
|
//}
|
|
//
|
|
//if (!mLandBuyHandle.isDead())
|
|
//{
|
|
// bool buyable = enable_buy_land(NULL);
|
|
// static_cast<LLMenuItemCallGL*>(mLandBuyHandle.get())->setEnabled(buyable);
|
|
//}
|
|
|
|
static LLView* land_buy_pass = gMenuHolder->getChildView("Land Buy Pass");
|
|
static LLView* land_buy_pass_pie = gMenuHolder->getChildView("Land Buy Pass Pie");
|
|
static LLView* land_buy = gMenuHolder->getChildView("Land Buy");
|
|
static LLView* land_buy_pie = gMenuHolder->getChildView("Land Buy Pie");
|
|
|
|
bool pass_buyable = LLPanelLandGeneral::enableBuyPass(nullptr) && parcel->getOwnerID() != gAgentID;
|
|
land_buy_pass->setEnabled(pass_buyable);
|
|
land_buy_pass_pie->setEnabled(pass_buyable);
|
|
|
|
bool buyable = enable_buy_land();
|
|
land_buy->setEnabled(buyable);
|
|
land_buy_pie->setEnabled(buyable);
|
|
// </FS:Ansariel> FIRE-4454: Cache controls because of performance reasons
|
|
}
|
|
}
|
|
|
|
|
|
void initialize_menus();
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Initialize main menus
|
|
//
|
|
// HOW TO NAME MENUS:
|
|
//
|
|
// First Letter Of Each Word Is Capitalized, Even At Or And
|
|
//
|
|
// Items that lead to dialog boxes end in "..."
|
|
//
|
|
// Break up groups of more than 6 items with separators
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void set_merchant_SLM_menu();
|
|
|
|
class LLSLMMenuUpdater
|
|
{
|
|
public:
|
|
LLSLMMenuUpdater();
|
|
~LLSLMMenuUpdater() = default;
|
|
|
|
void setMerchantMenu();
|
|
void checkMerchantStatus(bool force);
|
|
|
|
private:
|
|
LLHandle<LLView> mMarketplaceListingsItem;
|
|
};
|
|
|
|
static LLSLMMenuUpdater* gSLMMenuUpdater = NULL;
|
|
|
|
LLSLMMenuUpdater::LLSLMMenuUpdater()
|
|
{
|
|
mMarketplaceListingsItem = gMenuHolder->getChild<LLView>("MarketplaceListings")->getHandle();
|
|
}
|
|
void LLSLMMenuUpdater::setMerchantMenu()
|
|
{
|
|
// All other cases (new merchant, not merchant, migrated merchant): show the new Marketplace Listings menu and enable the tool
|
|
if(!mMarketplaceListingsItem.isDead())
|
|
{
|
|
mMarketplaceListingsItem.get()->setVisible(true);
|
|
}
|
|
LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
|
|
gToolBarView->enableCommand(command->id(), true);
|
|
|
|
const LLUUID marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS);
|
|
if (marketplacelistings_id.isNull())
|
|
{
|
|
U32 mkt_status = LLMarketplaceData::instance().getSLMStatus();
|
|
bool is_merchant = mkt_status == MarketplaceStatusCodes::MARKET_PLACE_MERCHANT || mkt_status == MarketplaceStatusCodes::MARKET_PLACE_MIGRATED_MERCHANT;
|
|
if (is_merchant)
|
|
{
|
|
gInventory.ensureCategoryForTypeExists(LLFolderType::FT_MARKETPLACE_LISTINGS);
|
|
LL_WARNS("SLM") << "Creating the marketplace listings folder for a merchant" << LL_ENDL;
|
|
}
|
|
}
|
|
}
|
|
|
|
void LLSLMMenuUpdater::checkMerchantStatus(bool force)
|
|
{
|
|
// <FS:Ansariel> Don't show merchant outbox or SL Marketplace stuff outside SL
|
|
if (!LLGridManager::getInstance()->isInSecondLife())
|
|
{
|
|
gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(false);
|
|
return;
|
|
}
|
|
// </FS:Ansariel>
|
|
|
|
if (force)
|
|
{
|
|
// Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status()
|
|
LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED);
|
|
}
|
|
// Hide SLM related menu item
|
|
if(!mMarketplaceListingsItem.isDead())
|
|
{
|
|
mMarketplaceListingsItem.get()->setVisible(false);
|
|
}
|
|
|
|
// Also disable the toolbar button for Marketplace Listings
|
|
LLCommand* command = LLCommandManager::instance().getCommand("marketplacelistings");
|
|
gToolBarView->enableCommand(command->id(), false);
|
|
|
|
// Launch an SLM test connection to get the merchant status
|
|
LLMarketplaceData::instance().initializeSLM(boost::bind(&set_merchant_SLM_menu));
|
|
}
|
|
|
|
void set_merchant_SLM_menu()
|
|
{
|
|
if (gSLMMenuUpdater)
|
|
gSLMMenuUpdater->setMerchantMenu();
|
|
}
|
|
|
|
void check_merchant_status(bool force)
|
|
{
|
|
if (gSLMMenuUpdater)
|
|
gSLMMenuUpdater->checkMerchantStatus(force);
|
|
}
|
|
|
|
void init_menus()
|
|
{
|
|
// Initialize actions
|
|
initialize_menus();
|
|
|
|
///
|
|
/// Popup menu
|
|
///
|
|
/// The popup menu is now populated by the show_context_menu()
|
|
/// method.
|
|
|
|
LLMenuGL::Params menu_params;
|
|
menu_params.name = "Popup";
|
|
menu_params.visible = false;
|
|
gPopupMenuView = LLUICtrlFactory::create<LLMenuGL>(menu_params);
|
|
gMenuHolder->addChild( gPopupMenuView );
|
|
|
|
///
|
|
/// Context menus
|
|
///
|
|
|
|
const widget_registry_t& registry =
|
|
LLViewerMenuHolderGL::child_registry_t::instance();
|
|
gEditMenu = LLUICtrlFactory::createFromFile<LLMenuGL>("menu_edit.xml", gMenuHolder, registry);
|
|
gMenuAvatarSelf = LLUICtrlFactory::createFromFile<LLContextMenu>(
|
|
"menu_avatar_self.xml", gMenuHolder, registry);
|
|
gMenuAvatarOther = LLUICtrlFactory::createFromFile<LLContextMenu>(
|
|
"menu_avatar_other.xml", gMenuHolder, registry);
|
|
|
|
gDetachScreenPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Detach HUD", true);
|
|
gDetachPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Detach", true);
|
|
|
|
gMenuObject = LLUICtrlFactory::createFromFile<LLContextMenu>(
|
|
"menu_object.xml", gMenuHolder, registry);
|
|
|
|
gAttachScreenPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Attach HUD");
|
|
gAttachPieMenu = gMenuHolder->getChild<LLContextMenu>("Object Attach");
|
|
|
|
gMenuAttachmentSelf = LLUICtrlFactory::createFromFile<LLContextMenu>(
|
|
"menu_attachment_self.xml", gMenuHolder, registry);
|
|
gMenuAttachmentOther = LLUICtrlFactory::createFromFile<LLContextMenu>(
|
|
"menu_attachment_other.xml", gMenuHolder, registry);
|
|
|
|
gDetachHUDAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self HUD", true);
|
|
gDetachAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self", true);
|
|
|
|
gMenuLand = LLUICtrlFactory::createFromFile<LLContextMenu>(
|
|
"menu_land.xml", gMenuHolder, registry);
|
|
|
|
gMenuMuteParticle = LLUICtrlFactory::createFromFile<LLContextMenu>(
|
|
"menu_mute_particle.xml", gMenuHolder, registry);
|
|
|
|
// <FS:Zi> Pie menu
|
|
gPieMenuAvatarSelf = LLUICtrlFactory::createFromFile<PieMenu>(
|
|
"menu_pie_avatar_self.xml", gMenuHolder, registry);
|
|
gPieMenuAvatarOther = LLUICtrlFactory::createFromFile<PieMenu>(
|
|
"menu_pie_avatar_other.xml", gMenuHolder, registry);
|
|
|
|
// added "Pie" to the control names to keep them unique
|
|
gPieDetachScreenMenu = gMenuHolder->getChild<PieMenu>("Pie Object Detach HUD", true);
|
|
gPieDetachMenu = gMenuHolder->getChild<PieMenu>("Pie Object Detach", true);
|
|
|
|
gPieMenuObject = LLUICtrlFactory::createFromFile<PieMenu>(
|
|
"menu_pie_object.xml", gMenuHolder, registry);
|
|
|
|
// added "Pie" to the control names to keep them unique
|
|
gPieAttachScreenMenu = gMenuHolder->getChild<PieMenu>("Pie Object Attach HUD");
|
|
gPieAttachMenu = gMenuHolder->getChild<PieMenu>("Pie Object Attach");
|
|
|
|
gPieMenuAttachmentSelf = LLUICtrlFactory::createFromFile<PieMenu>(
|
|
"menu_pie_attachment_self.xml", gMenuHolder, registry);
|
|
gPieMenuAttachmentOther = LLUICtrlFactory::createFromFile<PieMenu>(
|
|
"menu_pie_attachment_other.xml", gMenuHolder, registry);
|
|
|
|
gPieMenuLand = LLUICtrlFactory::createFromFile<PieMenu>(
|
|
"menu_pie_land.xml", gMenuHolder, registry);
|
|
|
|
gPieMenuMuteParticle = LLUICtrlFactory::createFromFile<PieMenu>(
|
|
"menu_pie_mute_particle.xml", gMenuHolder, registry);
|
|
// </FS:Zi> Pie menu
|
|
|
|
// <FS:Ansariel> FIRE-7893: Detach function on inspect self toast without function
|
|
gMenuInspectSelf = LLUICtrlFactory::createFromFile<LLToggleableMenu>(
|
|
"menu_inspect_self_gear.xml", gMenuHolder, registry);
|
|
|
|
gInspectSelfDetachScreenMenu = gMenuHolder->getChild<LLContextMenu>("Inspect Self Detach HUD", true);
|
|
gInspectSelfDetachMenu = gMenuHolder->getChild<LLContextMenu>("Inspect Self Detach", true);
|
|
// </FS:Ansariel>
|
|
|
|
///
|
|
/// set up the colors
|
|
///
|
|
// do not set colors in code, let the skin decide. -Zi
|
|
/*
|
|
LLUIColor context_menu_color = LLUIColorTable::instance().getColor("MenuPopupBgColor");
|
|
|
|
gMenuAvatarSelf->setBackgroundColor( context_menu_color );
|
|
gMenuAvatarOther->setBackgroundColor( context_menu_color );
|
|
gMenuObject->setBackgroundColor( context_menu_color );
|
|
gMenuAttachmentSelf->setBackgroundColor( context_menu_color );
|
|
gMenuAttachmentOther->setBackgroundColor( context_menu_color );
|
|
|
|
gMenuLand->setBackgroundColor( context_menu_color );
|
|
|
|
LLUIColor color = LLUIColorTable::instance().getColor( "MenuPopupBgColor" );
|
|
gPopupMenuView->setBackgroundColor( color );
|
|
*/
|
|
|
|
// <FS> Changed for grid manager
|
|
// If we are not in production, use a different color to make it apparent.
|
|
//if (LLGridManager::getInstance()->isInProductionGrid())
|
|
//{
|
|
// color = LLUIColorTable::instance().getColor( "MenuBarBgColor" );
|
|
//}
|
|
//else
|
|
//{
|
|
// color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
|
|
//}
|
|
|
|
//LLView* menu_bar_holder = gViewerWindow->getRootView()->getChildView("menu_bar_holder");
|
|
|
|
//gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_viewer.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
|
//gMenuBarView->setRect(LLRect(0, menu_bar_holder->getRect().mTop, 0, menu_bar_holder->getRect().mTop - MENU_BAR_HEIGHT));
|
|
//gMenuBarView->setBackgroundColor( color );
|
|
|
|
gMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_viewer.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
|
// ONLY change the color IF we are in beta. Otherwise leave it alone so it can use the skinned color. -Zi
|
|
if(LLGridManager::getInstance()->isInSLBeta())
|
|
{
|
|
LLUIColor color = LLUIColorTable::instance().getColor( "MenuNonProductionBgColor" );
|
|
gMenuBarView->setBackgroundColor( color );
|
|
}
|
|
|
|
LLView* menu_bar_holder = gViewerWindow->getRootView()->getChildView("menu_bar_holder");
|
|
gMenuBarView->setRect(LLRect(0, menu_bar_holder->getRect().mTop, 0, menu_bar_holder->getRect().mTop - MENU_BAR_HEIGHT));
|
|
// </FS> Changed for grid manager
|
|
|
|
menu_bar_holder->addChild(gMenuBarView);
|
|
|
|
gViewerWindow->setMenuBackgroundColor(false,
|
|
!LLGridManager::getInstance()->isInSLBeta());
|
|
// *TODO:Also fix cost in llfolderview.cpp for Inventory menus
|
|
const std::string sound_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getSoundUploadCost());
|
|
const std::string animation_upload_cost_str = std::to_string(LLAgentBenefitsMgr::current().getAnimationUploadCost());
|
|
gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", sound_upload_cost_str);
|
|
gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", animation_upload_cost_str);
|
|
|
|
gAutorespondMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Autorespond", true);
|
|
gAutorespondNonFriendsMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Autorespond to non-friends", true);
|
|
gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", true);
|
|
gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", true);
|
|
|
|
gDetachAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach", true);
|
|
gDetachHUDAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach HUD", true);
|
|
|
|
// Don't display the Memory console menu if the feature is turned off
|
|
LLMenuItemCheckGL *memoryMenu = gMenuBarView->getChild<LLMenuItemCheckGL>("Memory", true);
|
|
if (memoryMenu)
|
|
{
|
|
memoryMenu->setVisible(false);
|
|
}
|
|
|
|
gMenuBarView->createJumpKeys();
|
|
|
|
// Let land based option enable when parcel changes
|
|
gMenuParcelObserver = new LLMenuParcelObserver();
|
|
|
|
gSLMMenuUpdater = new LLSLMMenuUpdater();
|
|
|
|
gLoginMenuBarView = LLUICtrlFactory::getInstance()->createFromFile<LLMenuBarGL>("menu_login.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
|
gLoginMenuBarView->arrangeAndClear();
|
|
LLRect menuBarRect = gLoginMenuBarView->getRect();
|
|
menuBarRect.setLeftTopAndSize(0, menu_bar_holder->getRect().getHeight(), menuBarRect.getWidth(), menuBarRect.getHeight());
|
|
gLoginMenuBarView->setRect(menuBarRect);
|
|
// do not set colors in code, always lat the skin decide. -Zi
|
|
// gLoginMenuBarView->setBackgroundColor( color );
|
|
menu_bar_holder->addChild(gLoginMenuBarView);
|
|
|
|
// tooltips are on top of EVERYTHING, including menus
|
|
gViewerWindow->getRootView()->sendChildToFront(gToolTipView);
|
|
}
|
|
|
|
///////////////////
|
|
// SHOW CONSOLES //
|
|
///////////////////
|
|
|
|
|
|
class LLAdvancedToggleConsole : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string console_type = userdata.asString();
|
|
if ("texture" == console_type)
|
|
{
|
|
toggle_visibility(gTextureView);
|
|
}
|
|
else if ("debug" == console_type)
|
|
{
|
|
toggle_visibility(gDebugView->mDebugConsolep);
|
|
}
|
|
else if ("fast timers" == console_type)
|
|
{
|
|
LLFloaterReg::toggleInstance("block_timers");
|
|
}
|
|
else if ("scene view" == console_type)
|
|
{
|
|
toggle_visibility(gSceneView);
|
|
}
|
|
else if ("scene monitor" == console_type)
|
|
{
|
|
toggle_visibility(gSceneMonitorView);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
class LLAdvancedCheckConsole : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string console_type = userdata.asString();
|
|
bool new_value = false;
|
|
if ("texture" == console_type)
|
|
{
|
|
new_value = get_visibility(gTextureView);
|
|
}
|
|
else if ("debug" == console_type)
|
|
{
|
|
new_value = get_visibility(gDebugView->mDebugConsolep);
|
|
}
|
|
else if ("fast timers" == console_type)
|
|
{
|
|
new_value = LLFloaterReg::instanceVisible("block_timers");
|
|
}
|
|
else if ("scene view" == console_type)
|
|
{
|
|
new_value = get_visibility(gSceneView);
|
|
}
|
|
else if ("scene monitor" == console_type)
|
|
{
|
|
new_value = get_visibility(gSceneMonitorView);
|
|
}
|
|
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
//////////////////////////
|
|
// DUMP INFO TO CONSOLE //
|
|
//////////////////////////
|
|
|
|
|
|
class LLAdvancedDumpInfoToConsole : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gDebugView->mDebugConsolep->setVisible(true);
|
|
std::string info_type = userdata.asString();
|
|
if ("region" == info_type)
|
|
{
|
|
handle_region_dump_settings();
|
|
}
|
|
else if ("group" == info_type)
|
|
{
|
|
handle_dump_group_info();
|
|
}
|
|
else if ("capabilities" == info_type)
|
|
{
|
|
handle_dump_capabilities_info();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
//////////////
|
|
// HUD INFO //
|
|
//////////////
|
|
|
|
|
|
class LLAdvancedToggleHUDInfo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string info_type = userdata.asString();
|
|
|
|
if ("camera" == info_type)
|
|
{
|
|
gDisplayCameraPos = !(gDisplayCameraPos);
|
|
}
|
|
else if ("wind" == info_type)
|
|
{
|
|
gDisplayWindInfo = !(gDisplayWindInfo);
|
|
}
|
|
else if ("fov" == info_type)
|
|
{
|
|
gDisplayFOV = !(gDisplayFOV);
|
|
}
|
|
else if ("badge" == info_type)
|
|
{
|
|
FSCommon::report_to_nearby_chat("Hippos!");
|
|
}
|
|
else if ("cookies" == info_type)
|
|
{
|
|
FSCommon::report_to_nearby_chat("Cookies!");
|
|
}
|
|
// <FS:PP>
|
|
else if ("motd" == info_type)
|
|
{
|
|
FSCommon::report_to_nearby_chat(gAgent.mMOTD);
|
|
}
|
|
// </FS:PP>
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckHUDInfo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string info_type = userdata.asString();
|
|
bool new_value = false;
|
|
if ("camera" == info_type)
|
|
{
|
|
new_value = gDisplayCameraPos;
|
|
}
|
|
else if ("wind" == info_type)
|
|
{
|
|
new_value = gDisplayWindInfo;
|
|
}
|
|
else if ("fov" == info_type)
|
|
{
|
|
new_value = gDisplayFOV;
|
|
}
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
// <FS:Ansariel> Keep this for menu check item
|
|
//////////////
|
|
// FLYING //
|
|
//////////////
|
|
|
|
class LLAdvancedAgentFlyingInfo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD&)
|
|
{
|
|
return gAgent.getFlying();
|
|
}
|
|
};
|
|
// </FS:Ansariel>
|
|
|
|
|
|
///////////////////////
|
|
// CLEAR GROUP CACHE //
|
|
///////////////////////
|
|
|
|
class LLAdvancedClearGroupCache : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLGroupMgr::debugClearAllGroups(nullptr);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
/////////////////
|
|
// RENDER TYPE //
|
|
/////////////////
|
|
U32 render_type_from_string(std::string_view render_type)
|
|
{
|
|
if ("simple" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_SIMPLE;
|
|
}
|
|
if ("materials" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_MATERIALS;
|
|
}
|
|
else if ("alpha" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_ALPHA;
|
|
}
|
|
else if ("alpha_mask" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_ALPHA_MASK;
|
|
}
|
|
else if ("fullbright_alpha_mask" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_FULLBRIGHT_ALPHA_MASK;
|
|
}
|
|
else if ("fullbright" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_FULLBRIGHT;
|
|
}
|
|
else if ("glow" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_GLOW;
|
|
}
|
|
else if ("tree" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_TREE;
|
|
}
|
|
else if ("character" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_AVATAR;
|
|
}
|
|
else if ("controlAV" == render_type) // Animesh
|
|
{
|
|
return LLPipeline::RENDER_TYPE_CONTROL_AV;
|
|
}
|
|
else if ("surfacePatch" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_TERRAIN;
|
|
}
|
|
else if ("sky" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_SKY;
|
|
}
|
|
else if ("water" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_WATER;
|
|
}
|
|
else if ("volume" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_VOLUME;
|
|
}
|
|
else if ("grass" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_GRASS;
|
|
}
|
|
else if ("clouds" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_CLOUDS;
|
|
}
|
|
else if ("particles" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_PARTICLES;
|
|
}
|
|
else if ("bump" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_BUMP;
|
|
}
|
|
else if ("pbr" == render_type)
|
|
{
|
|
return LLPipeline::RENDER_TYPE_GLTF_PBR;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
class LLAdvancedToggleRenderType : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
U32 render_type = render_type_from_string( userdata.asString() );
|
|
if ( render_type != 0 )
|
|
{
|
|
LLPipeline::toggleRenderTypeControl( render_type );
|
|
if(render_type == LLPipeline::RENDER_TYPE_PARTICLES)
|
|
{
|
|
gPipeline.sRenderParticles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
class LLAdvancedCheckRenderType : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
U32 render_type = render_type_from_string( userdata.asString() );
|
|
bool new_value = false;
|
|
|
|
if ( render_type != 0 )
|
|
{
|
|
new_value = LLPipeline::hasRenderTypeControl( render_type );
|
|
}
|
|
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
/////////////
|
|
// FEATURE //
|
|
/////////////
|
|
U32 feature_from_string(std::string_view feature)
|
|
{
|
|
if ("ui" == feature)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_FEATURE_UI;
|
|
}
|
|
else if ("selected" == feature)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_FEATURE_SELECTED;
|
|
}
|
|
else if ("highlighted" == feature)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_FEATURE_HIGHLIGHTED;
|
|
}
|
|
else if ("dynamic textures" == feature)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES;
|
|
}
|
|
else if ("foot shadows" == feature)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS;
|
|
}
|
|
else if ("fog" == feature)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_FEATURE_FOG;
|
|
}
|
|
else if ("fr info" == feature)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_FEATURE_FR_INFO;
|
|
}
|
|
else if ("flexible" == feature)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE;
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
|
|
class LLAdvancedToggleFeature : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
U32 feature = feature_from_string( userdata.asString() );
|
|
if ( feature != 0 )
|
|
{
|
|
LLPipeline::toggleRenderDebugFeature( feature );
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckFeature : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
U32 feature = feature_from_string( userdata.asString() );
|
|
bool new_value = false;
|
|
|
|
if ( feature != 0 )
|
|
{
|
|
new_value = LLPipeline::toggleRenderDebugFeatureControl( feature );
|
|
}
|
|
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckDisplayTextureDensity : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string mode = userdata.asString();
|
|
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
|
|
{
|
|
return mode == "none";
|
|
}
|
|
if (mode == "current")
|
|
{
|
|
return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_CURRENT;
|
|
}
|
|
else if (mode == "desired")
|
|
{
|
|
return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_DESIRED;
|
|
}
|
|
else if (mode == "full")
|
|
{
|
|
return LLViewerTexture::sDebugTexelsMode == LLViewerTexture::DEBUG_TEXELS_FULL;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedSetDisplayTextureDensity : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string mode = userdata.asString();
|
|
if (mode == "none")
|
|
{
|
|
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
|
|
{
|
|
gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
|
|
}
|
|
LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_OFF;
|
|
}
|
|
else if (mode == "current")
|
|
{
|
|
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
|
|
{
|
|
gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
|
|
}
|
|
LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_CURRENT;
|
|
}
|
|
else if (mode == "desired")
|
|
{
|
|
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
|
|
{
|
|
gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
|
|
}
|
|
gPipeline.setRenderDebugFeatureControl(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY, true);
|
|
LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_DESIRED;
|
|
}
|
|
else if (mode == "full")
|
|
{
|
|
if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY))
|
|
{
|
|
gPipeline.toggleRenderDebug(LLPipeline::RENDER_DEBUG_TEXEL_DENSITY);
|
|
}
|
|
LLViewerTexture::sDebugTexelsMode = LLViewerTexture::DEBUG_TEXELS_FULL;
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
//////////////////
|
|
// INFO DISPLAY //
|
|
//////////////////
|
|
U64 info_display_from_string(std::string_view info_display)
|
|
{
|
|
if ("verify" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_VERIFY;
|
|
}
|
|
else if ("bboxes" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_BBOXES;
|
|
}
|
|
else if ("normals" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_NORMALS;
|
|
}
|
|
else if ("points" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_POINTS;
|
|
}
|
|
else if ("octree" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_OCTREE;
|
|
}
|
|
else if ("nodes" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_NODES;
|
|
}
|
|
else if ("shadow frusta" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA;
|
|
}
|
|
else if ("physics shapes" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES;
|
|
}
|
|
else if ("occlusion" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_OCCLUSION;
|
|
}
|
|
else if ("render batches" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_BATCH_SIZE;
|
|
}
|
|
else if ("update type" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_UPDATE_TYPE;
|
|
}
|
|
else if ("texture anim" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_TEXTURE_ANIM;
|
|
}
|
|
else if ("texture priority" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY;
|
|
}
|
|
else if ("texture area" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_TEXTURE_AREA;
|
|
}
|
|
else if ("face area" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_FACE_AREA;
|
|
}
|
|
else if ("lod info" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_LOD_INFO;
|
|
}
|
|
else if ("lights" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_LIGHTS;
|
|
}
|
|
else if ("particles" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_PARTICLES;
|
|
}
|
|
else if ("composition" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_COMPOSITION;
|
|
}
|
|
else if ("avatardrawinfo" == info_display)
|
|
{
|
|
return (LLPipeline::RENDER_DEBUG_AVATAR_DRAW_INFO);
|
|
}
|
|
else if ("glow" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_GLOW;
|
|
}
|
|
else if ("collision skeleton" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_AVATAR_VOLUME;
|
|
}
|
|
else if ("joints" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_AVATAR_JOINTS;
|
|
}
|
|
else if ("raycast" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_RAYCAST;
|
|
}
|
|
else if ("agent target" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_AGENT_TARGET;
|
|
}
|
|
else if ("sculpt" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_SCULPTED;
|
|
}
|
|
else if ("wind vectors" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_WIND_VECTORS;
|
|
}
|
|
else if ("texel density" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_TEXEL_DENSITY;
|
|
}
|
|
else if ("triangle count" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_TRIANGLE_COUNT;
|
|
}
|
|
else if ("impostors" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_IMPOSTORS;
|
|
}
|
|
else if ("reflection probes" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_REFLECTION_PROBES;
|
|
}
|
|
else if ("probe updates" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_PROBE_UPDATES;
|
|
}
|
|
else if ("texture size" == info_display)
|
|
{
|
|
return LLPipeline::RENDER_DEBUG_TEXTURE_SIZE;
|
|
}
|
|
else
|
|
{
|
|
LL_WARNS() << "unrecognized feature name '" << info_display << "'" << LL_ENDL;
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedToggleInfoDisplay : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
U64 info_display = info_display_from_string( userdata.asString() );
|
|
|
|
LL_INFOS("ViewerMenu") << "toggle " << userdata.asString() << LL_ENDL;
|
|
|
|
if ( info_display != 0 )
|
|
{
|
|
LLPipeline::toggleRenderDebug( info_display );
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
class LLAdvancedCheckInfoDisplay : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
U64 info_display = info_display_from_string( userdata.asString() );
|
|
bool new_value = false;
|
|
|
|
if ( info_display != 0 )
|
|
{
|
|
new_value = LLPipeline::toggleRenderDebugControl( info_display );
|
|
}
|
|
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
///////////////////////////
|
|
//// RANDOMIZE FRAMERATE //
|
|
///////////////////////////
|
|
|
|
|
|
class LLAdvancedToggleRandomizeFramerate : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gRandomizeFramerate = !(gRandomizeFramerate);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckRandomizeFramerate : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gRandomizeFramerate;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
///////////////////////////
|
|
//// PERIODIC SLOW FRAME //
|
|
///////////////////////////
|
|
|
|
|
|
class LLAdvancedTogglePeriodicSlowFrame : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gPeriodicSlowFrame = !(gPeriodicSlowFrame);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckPeriodicSlowFrame : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gPeriodicSlowFrame;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
///////////////////////////
|
|
// SELECTED TEXTURE INFO //
|
|
//
|
|
///////////////////////////
|
|
|
|
|
|
class LLAdvancedSelectedTextureInfo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_selected_texture_info();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
//////////////////////
|
|
// TOGGLE WIREFRAME //
|
|
//////////////////////
|
|
|
|
class LLAdvancedToggleWireframe : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// [RLVa:KB] - @detach and @viewwireframe
|
|
const bool fRlvCanViewWireframe = RlvActions::canViewWireframe();
|
|
if ( (!gUseWireframe) && (!fRlvCanViewWireframe) )
|
|
RlvUtil::notifyBlocked(RlvStringKeys::Blocked::Wireframe);
|
|
set_use_wireframe( (!gUseWireframe) && (fRlvCanViewWireframe) );
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// Called from rlvhandler.cpp
|
|
void set_use_wireframe(bool useWireframe)
|
|
{
|
|
if (gUseWireframe == useWireframe)
|
|
return;
|
|
|
|
gUseWireframe = useWireframe;
|
|
// [/RLVa:KB]
|
|
// gUseWireframe = !(gUseWireframe);
|
|
|
|
// return true;
|
|
}
|
|
//};
|
|
|
|
class LLAdvancedCheckWireframe : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return gUseWireframe;
|
|
}
|
|
};
|
|
|
|
|
|
//////////////////////////
|
|
// DUMP SCRIPTED CAMERA //
|
|
//////////////////////////
|
|
|
|
class LLAdvancedDumpScriptedCamera : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_dump_followcam();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
//////////////////////////////
|
|
// DUMP REGION OBJECT CACHE //
|
|
//////////////////////////////
|
|
|
|
|
|
class LLAdvancedDumpRegionObjectCache : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_dump_region_object_cache();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedToggleInterestList360Mode : public view_listener_t
|
|
{
|
|
public:
|
|
bool handleEvent(const LLSD &userdata)
|
|
{
|
|
// Toggle the mode - regions will get updated
|
|
if (gAgent.getInterestListMode() == IL_MODE_360)
|
|
{
|
|
// <FS:Beq> we need to force the 360 mode "users" to false or this override will fail
|
|
gAgent.setFSAreaSearchActive(false);
|
|
gAgent.set360CaptureActive(false);
|
|
// <FS:Beq/>
|
|
gAgent.changeInterestListMode(IL_MODE_DEFAULT);
|
|
}
|
|
else
|
|
{
|
|
// <FS:Beq> we need to force the 360 mode user flag to true or this override will fail. Don;t set area search though as that can have other effects.
|
|
gAgent.set360CaptureActive(false);
|
|
// <FS:Beq/>
|
|
gAgent.changeInterestListMode(IL_MODE_360);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckInterestList360Mode : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return (gAgent.getInterestListMode() == IL_MODE_360);
|
|
}
|
|
};
|
|
|
|
class LLAdvancedToggleStatsRecorder : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD &userdata)
|
|
{
|
|
if (LLViewerStatsRecorder::instance().isEnabled())
|
|
{ // Turn off both recording and logging
|
|
LLViewerStatsRecorder::instance().enableObjectStatsRecording(false);
|
|
}
|
|
else
|
|
{ // Turn on both recording and logging
|
|
LLViewerStatsRecorder::instance().enableObjectStatsRecording(true, true);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckStatsRecorder : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD &userdata)
|
|
{ // Use the logging state as the indicator of whether the stats recorder is on
|
|
return LLViewerStatsRecorder::instance().isLogging();
|
|
}
|
|
};
|
|
|
|
class LLAdvancedResetInterestLists : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD &userdata)
|
|
{ // Reset all region interest lists
|
|
handle_reset_interest_lists();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
/////////////
|
|
// TERRAIN //
|
|
/////////////
|
|
|
|
class LLAdvancedRebuildTerrain : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gPipeline.rebuildTerrain();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedTerrainCreateLocalPaintMap : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLViewerRegion* region = gAgent.getRegion();
|
|
if (!region)
|
|
{
|
|
LL_WARNS() << "Agent not in a region" << LL_ENDL;
|
|
return false;
|
|
}
|
|
|
|
U16 dim = (U16)gSavedSettings.getU32("TerrainPaintResolution");
|
|
// Ensure a reasonable image size of power two
|
|
const U32 max_resolution = gSavedSettings.getU32("RenderMaxTextureResolution");
|
|
dim = llclamp(dim, 16, max_resolution);
|
|
dim = 1 << U32(std::ceil(std::log2(dim)));
|
|
LLPointer<LLImageRaw> image_raw = new LLImageRaw(dim,dim,3);
|
|
LLPointer<LLViewerTexture> tex = LLViewerTextureManager::getLocalTexture(image_raw.get(), true);
|
|
const bool success = LLTerrainPaintMap::bakeHeightNoiseIntoPBRPaintMapRGB(*region, *tex);
|
|
// This calls gLocalTerrainMaterials.setPaintType
|
|
gSavedSettings.setBOOL("LocalTerrainPaintEnabled", true);
|
|
// If baking the paintmap failed, set the paintmap to nullptr. This
|
|
// causes LLDrawPoolTerrain to use a blank paintmap instead.
|
|
if (!success) { tex = nullptr; }
|
|
gLocalTerrainMaterials.setPaintMap(tex);
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedTerrainDeleteLocalPaintMap : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// This calls gLocalTerrainMaterials.setPaintType
|
|
gSavedSettings.setBOOL("LocalTerrainPaintEnabled", false);
|
|
gLocalTerrainMaterials.setPaintMap(nullptr);
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
/////////////
|
|
|
|
|
|
class LLAdvancedBuyCurrencyTest : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_buy_currency_test();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
/////////////////////
|
|
// DUMP SELECT MGR //
|
|
/////////////////////
|
|
|
|
|
|
class LLAdvancedDumpSelectMgr : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
dump_select_mgr();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
////////////////////
|
|
// DUMP INVENTORY //
|
|
////////////////////
|
|
|
|
|
|
class LLAdvancedDumpInventory : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
dump_inventory();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
////////////////////////////////
|
|
// PRINT SELECTED OBJECT INFO //
|
|
////////////////////////////////
|
|
|
|
|
|
class LLAdvancedPrintSelectedObjectInfo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
print_object_info();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
//////////////////////
|
|
// PRINT AGENT INFO //
|
|
//////////////////////
|
|
|
|
|
|
class LLAdvancedPrintAgentInfo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
print_agent_nvpairs();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
//////////////////
|
|
// DEBUG CLICKS //
|
|
//////////////////
|
|
|
|
|
|
class LLAdvancedToggleDebugClicks : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gDebugClicks = !(gDebugClicks);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckDebugClicks : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gDebugClicks;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/////////////////
|
|
// DEBUG VIEWS //
|
|
/////////////////
|
|
|
|
|
|
class LLAdvancedToggleDebugViews : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLView::sDebugRects = !(LLView::sDebugRects);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckDebugViews : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLView::sDebugRects;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
///////////////////
|
|
// DEBUG UNICODE //
|
|
///////////////////
|
|
|
|
|
|
class LLAdvancedToggleDebugUnicode : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLView::sDebugUnicode = !(LLView::sDebugUnicode);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckDebugUnicode : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return LLView::sDebugUnicode;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
//////////////////
|
|
// DEBUG CAMERA //
|
|
//////////////////
|
|
|
|
|
|
class LLAdvancedToggleDebugCamera : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLView::sDebugCamera = !(LLView::sDebugCamera);
|
|
LLFloaterCamera::onDebugCameraToggled();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckDebugCamera : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return LLView::sDebugCamera;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
///////////////////////
|
|
// XUI NAME TOOLTIPS //
|
|
///////////////////////
|
|
|
|
|
|
class LLAdvancedToggleXUINameTooltips : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
toggle_show_xui_names();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckXUINameTooltips : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = check_show_xui_names();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
////////////////////////
|
|
// DEBUG MOUSE EVENTS //
|
|
////////////////////////
|
|
|
|
|
|
class LLAdvancedToggleDebugMouseEvents : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLView::sDebugMouseHandling = !(LLView::sDebugMouseHandling);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckDebugMouseEvents : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLView::sDebugMouseHandling;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
////////////////
|
|
// DEBUG KEYS //
|
|
////////////////
|
|
|
|
|
|
class LLAdvancedToggleDebugKeys : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLView::sDebugKeys = !(LLView::sDebugKeys);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckDebugKeys : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLView::sDebugKeys;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
///////////////////////
|
|
// DEBUG WINDOW PROC //
|
|
///////////////////////
|
|
|
|
|
|
class LLAdvancedToggleDebugWindowProc : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gDebugWindowProc = !(gDebugWindowProc);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckDebugWindowProc : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gDebugWindowProc;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
// ------------------------------XUI MENU ---------------------------
|
|
|
|
//////////////////////
|
|
// LOAD UI FROM XML //
|
|
//////////////////////
|
|
|
|
|
|
class LLAdvancedLoadUIFromXML : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_load_from_xml(NULL);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
////////////////////
|
|
// SAVE UI TO XML //
|
|
////////////////////
|
|
|
|
|
|
class LLAdvancedSaveUIToXML : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_save_to_xml(NULL);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
class LLAdvancedSendTestIms : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLIMModel::instance().testMessages();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
///////////////
|
|
// XUI NAMES //
|
|
///////////////
|
|
|
|
|
|
class LLAdvancedToggleXUINames : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
toggle_show_xui_names();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckXUINames : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = check_show_xui_names();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
////////////////////////
|
|
// GRAB BAKED TEXTURE //
|
|
////////////////////////
|
|
|
|
|
|
class LLAdvancedGrabBakedTexture : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string texture_type = userdata.asString();
|
|
if ("iris" == texture_type)
|
|
{
|
|
handle_grab_baked_texture(BAKED_EYES);
|
|
}
|
|
else if ("head" == texture_type)
|
|
{
|
|
handle_grab_baked_texture(BAKED_HEAD);
|
|
}
|
|
else if ("upper" == texture_type)
|
|
{
|
|
handle_grab_baked_texture(BAKED_UPPER);
|
|
}
|
|
else if ("lower" == texture_type)
|
|
{
|
|
handle_grab_baked_texture(BAKED_LOWER);
|
|
}
|
|
else if ("skirt" == texture_type)
|
|
{
|
|
handle_grab_baked_texture(BAKED_SKIRT);
|
|
}
|
|
else if ("hair" == texture_type)
|
|
{
|
|
handle_grab_baked_texture(BAKED_HAIR);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedEnableGrabBakedTexture : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string texture_type = userdata.asString();
|
|
bool new_value = false;
|
|
|
|
if ("iris" == texture_type)
|
|
{
|
|
new_value = enable_grab_baked_texture(BAKED_EYES);
|
|
}
|
|
else if ("head" == texture_type)
|
|
{
|
|
new_value = enable_grab_baked_texture(BAKED_HEAD);
|
|
}
|
|
else if ("upper" == texture_type)
|
|
{
|
|
new_value = enable_grab_baked_texture(BAKED_UPPER);
|
|
}
|
|
else if ("lower" == texture_type)
|
|
{
|
|
new_value = enable_grab_baked_texture(BAKED_LOWER);
|
|
}
|
|
else if ("skirt" == texture_type)
|
|
{
|
|
new_value = enable_grab_baked_texture(BAKED_SKIRT);
|
|
}
|
|
else if ("hair" == texture_type)
|
|
{
|
|
new_value = enable_grab_baked_texture(BAKED_HAIR);
|
|
}
|
|
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
///////////////////////
|
|
// APPEARANCE TO XML //
|
|
///////////////////////
|
|
|
|
|
|
class LLAdvancedEnableAppearanceToXML : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (obj && obj->isAnimatedObject() && obj->getControlAvatar())
|
|
{
|
|
return gSavedSettings.getBOOL("DebugAnimatedObjects");
|
|
}
|
|
else if (obj && obj->isAttachment() && obj->getAvatar())
|
|
{
|
|
return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
|
|
}
|
|
else if (obj && obj->isAvatar())
|
|
{
|
|
// This has to be a non-control avatar, because control avs are invisible and unclickable.
|
|
return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
};
|
|
|
|
class LLAdvancedAppearanceToXML : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string emptyname;
|
|
LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
LLVOAvatar *avatar = NULL;
|
|
if (obj)
|
|
{
|
|
if (obj->isAvatar())
|
|
{
|
|
avatar = obj->asAvatar();
|
|
}
|
|
else
|
|
{
|
|
// If there is a selection, find the associated
|
|
// avatar. Normally there's only one obvious choice. But
|
|
// what should be returned if the object is in an attached
|
|
// animated object? getAvatar() will give the skeleton of
|
|
// the animated object. getAvatarAncestor() will give the
|
|
// actual human-driven avatar.
|
|
avatar = obj->getAvatar();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// If no selection, use the self avatar.
|
|
avatar = gAgentAvatarp;
|
|
}
|
|
if (avatar)
|
|
{
|
|
avatar->dumpArchetypeXML(emptyname);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
///////////////////////////////
|
|
// TOGGLE CHARACTER GEOMETRY //
|
|
///////////////////////////////
|
|
|
|
|
|
class LLAdvancedToggleCharacterGeometry : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_god_request_avatar_geometry();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
/////////////////////////////
|
|
// TEST MALE / TEST FEMALE //
|
|
/////////////////////////////
|
|
|
|
class LLAdvancedTestMale : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_test_male();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
class LLAdvancedTestFemale : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_test_female();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedForceParamsToDefault : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLAgent::clearVisualParams(nullptr);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
//////////////////////////
|
|
// ANIMATION SPEED //
|
|
//////////////////////////
|
|
|
|
// Utility function to set all AV time factors to the same global value
|
|
static void set_all_animation_time_factors(F32 time_factor)
|
|
{
|
|
LLMotionController::setCurrentTimeFactor(time_factor);
|
|
for (LLCharacter* character : LLCharacter::sInstances)
|
|
{
|
|
character->setAnimTimeFactor(time_factor);
|
|
}
|
|
}
|
|
|
|
class LLAdvancedAnimTenFaster : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
//LL_INFOS() << "LLAdvancedAnimTenFaster" << LL_ENDL;
|
|
F32 time_factor = LLMotionController::getCurrentTimeFactor();
|
|
time_factor = llmin(time_factor + 0.1f, 2.f); // Upper limit is 200% speed
|
|
set_all_animation_time_factors(time_factor);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedAnimTenSlower : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
//LL_INFOS() << "LLAdvancedAnimTenSlower" << LL_ENDL;
|
|
F32 time_factor = LLMotionController::getCurrentTimeFactor();
|
|
time_factor = llmax(time_factor - 0.1f, 0.1f); // Lower limit is at 10% of normal speed
|
|
set_all_animation_time_factors(time_factor);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedAnimResetAll : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
set_all_animation_time_factors(1.f);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
//////////////////////////
|
|
// RELOAD VERTEX SHADER //
|
|
//////////////////////////
|
|
|
|
|
|
class LLAdvancedReloadVertexShader : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
reload_vertex_shader();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
////////////////////
|
|
// ANIMATION INFO //
|
|
////////////////////
|
|
|
|
|
|
class LLAdvancedToggleAnimationInfo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar::sShowAnimationDebug = !(LLVOAvatar::sShowAnimationDebug);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckAnimationInfo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLVOAvatar::sShowAnimationDebug;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
//////////////////
|
|
// SHOW LOOK AT //
|
|
//////////////////
|
|
|
|
|
|
class LLAdvancedToggleShowLookAt : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
//LLHUDEffectLookAt::sDebugLookAt = !(LLHUDEffectLookAt::sDebugLookAt);
|
|
//<FS:AO improve use of controls with radiogroups>
|
|
//bool value = !gSavedPerAccountSettings.getBOOL("DebugLookAt");
|
|
//gSavedPerAccountSettings.setBOOL("DebugLookAt",value);
|
|
S32 value = gSavedPerAccountSettings.getS32("DebugLookAt") == 0 ? 1 : 0;
|
|
gSavedPerAccountSettings.setS32("DebugLookAt", value);
|
|
//</FS:AO>
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// <AO>
|
|
class LLAdvancedToggleShowColor : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
S32 value = gSavedSettings.getS32("DebugShowColor") == 0 ? 1 : 0;
|
|
gSavedSettings.setS32("DebugShowColor", value);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckShowColor : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gSavedSettings.getS32("DebugShowColor") != 0;
|
|
return new_value;
|
|
}
|
|
};
|
|
// </AO>
|
|
|
|
class LLAdvancedCheckShowLookAt : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
//bool new_value = LLHUDEffectLookAt::sDebugLookAt;
|
|
//<FS:AO improve use of controls with radiogroups>
|
|
//bool new_value = gSavedPerAccountSettings.getBOOL("DebugLookAt");
|
|
bool new_value = gSavedPerAccountSettings.getS32("DebugLookAt") > 0;
|
|
return (bool)new_value;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
///////////////////
|
|
// SHOW POINT AT //
|
|
///////////////////
|
|
|
|
|
|
class LLAdvancedToggleShowPointAt : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLHUDEffectPointAt::sDebugPointAt = !(LLHUDEffectPointAt::sDebugPointAt);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckShowPointAt : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLHUDEffectPointAt::sDebugPointAt;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
/////////////////////
|
|
// PRIVATE LOOK AT //
|
|
/////////////////////
|
|
|
|
class LLAdvancedTogglePrivateLookPointAt : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string command = userdata.asString();
|
|
if ("Look" == command)
|
|
{
|
|
bool new_value = !gSavedSettings.getBOOL("PrivateLookAtTarget");
|
|
gSavedSettings.setBOOL("PrivateLookAtTarget", new_value);
|
|
}
|
|
else if ("Point" == command)
|
|
{
|
|
bool new_value = !gSavedSettings.getBOOL("PrivatePointAtTarget");
|
|
gSavedSettings.setBOOL("PrivatePointAtTarget", new_value);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckPrivateLookPointAt : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string command = userdata["data"].asString();
|
|
if ("Look" == command)
|
|
{
|
|
bool new_value = gSavedSettings.getBOOL("PrivateLookAtTarget");
|
|
std::string control_name = userdata["control"].asString();
|
|
gMenuHolder->findControl(control_name)->setValue(new_value);
|
|
}
|
|
else if ("Point" == command)
|
|
{
|
|
bool new_value = gSavedSettings.getBOOL("PrivatePointAtTarget");
|
|
std::string control_name = userdata["control"].asString();
|
|
gMenuHolder->findControl(control_name)->setValue(new_value);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/////////////////////////
|
|
// DEBUG JOINT UPDATES //
|
|
/////////////////////////
|
|
|
|
|
|
class LLAdvancedToggleDebugJointUpdates : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar::sJointDebug = !(LLVOAvatar::sJointDebug);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckDebugJointUpdates : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLVOAvatar::sJointDebug;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/////////////////
|
|
// DISABLE LOD //
|
|
/////////////////
|
|
|
|
|
|
class LLAdvancedToggleDisableLOD : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLViewerJoint::sDisableLOD = !(LLViewerJoint::sDisableLOD);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckDisableLOD : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLViewerJoint::sDisableLOD;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/////////////////////////
|
|
// DEBUG CHARACTER VIS //
|
|
/////////////////////////
|
|
|
|
|
|
class LLAdvancedToggleDebugCharacterVis : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar::sDebugInvisible = !(LLVOAvatar::sDebugInvisible);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckDebugCharacterVis : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLVOAvatar::sDebugInvisible;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
//////////////////////
|
|
// DUMP ATTACHMENTS //
|
|
//////////////////////
|
|
|
|
|
|
class LLAdvancedDumpAttachments : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_dump_attachments();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
/////////////////////
|
|
// REBAKE TEXTURES //
|
|
/////////////////////
|
|
|
|
|
|
class LLAdvancedRebakeTextures : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_rebake_textures();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
|
|
void handle_refresh_attachments()
|
|
{
|
|
LLAttachmentsMgr::instance().refreshAttachments();
|
|
}
|
|
// [/SL:KB]
|
|
|
|
#if 1 //ndef LL_RELEASE_FOR_DOWNLOAD
|
|
///////////////////////////
|
|
// DEBUG AVATAR TEXTURES //
|
|
///////////////////////////
|
|
|
|
|
|
class LLAdvancedDebugAvatarTextures : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (gAgent.isGodlike())
|
|
{
|
|
handle_debug_avatar_textures();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
////////////////////////////////
|
|
// DUMP AVATAR LOCAL TEXTURES //
|
|
////////////////////////////////
|
|
|
|
|
|
class LLAdvancedDumpAvatarLocalTextures : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
#ifndef LL_RELEASE_FOR_DOWNLOAD
|
|
handle_dump_avatar_local_textures();
|
|
#endif
|
|
return true;
|
|
}
|
|
};
|
|
|
|
#endif
|
|
|
|
///////////////////////////////////
|
|
// Reload Avatar Cloud Particles //
|
|
///////////////////////////////////
|
|
class LLAdvancedReloadAvatarCloudParticle : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar::initCloud();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/////////////////
|
|
// MESSAGE LOG //
|
|
/////////////////
|
|
|
|
|
|
class LLAdvancedEnableMessageLog : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_viewer_enable_message_log();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedDisableMessageLog : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_viewer_disable_message_log();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/////////////////
|
|
// DROP PACKET //
|
|
/////////////////
|
|
|
|
|
|
class LLAdvancedDropPacket : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gMessageSystem->mPacketRing.dropPackets(1);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
//////////////////////
|
|
// PURGE DISK CACHE //
|
|
//////////////////////
|
|
|
|
|
|
class LLAdvancedPurgeDiskCache : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
|
|
LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
|
|
llassert_always(main_queue);
|
|
llassert_always(general_queue);
|
|
main_queue->postTo(
|
|
general_queue,
|
|
[]() // Work done on general queue
|
|
{
|
|
LLDiskCache::getInstance()->purge();
|
|
// Nothing needed to return
|
|
},
|
|
[](){}); // Callback to main thread is empty as there is nothing left to do
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
////////////////////////
|
|
// PURGE SHADER CACHE //
|
|
////////////////////////
|
|
|
|
|
|
class LLAdvancedPurgeShaderCache : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLViewerShaderMgr::instance()->clearShaderCache();
|
|
LLViewerShaderMgr::instance()->setShaders();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
////////////////////
|
|
// EVENT Recorder //
|
|
///////////////////
|
|
|
|
|
|
class LLAdvancedViewerEventRecorder : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string command = userdata.asString();
|
|
if ("start playback" == command)
|
|
{
|
|
LL_INFOS() << "Event Playback starting" << LL_ENDL;
|
|
LLViewerEventRecorder::instance().playbackRecording();
|
|
LL_INFOS() << "Event Playback completed" << LL_ENDL;
|
|
}
|
|
else if ("stop playback" == command)
|
|
{
|
|
// Future
|
|
}
|
|
else if ("start recording" == command)
|
|
{
|
|
LLViewerEventRecorder::instance().setEventLoggingOn();
|
|
LL_INFOS() << "Event recording started" << LL_ENDL;
|
|
}
|
|
else if ("stop recording" == command)
|
|
{
|
|
LLViewerEventRecorder::instance().setEventLoggingOff();
|
|
LL_INFOS() << "Event recording stopped" << LL_ENDL;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
/////////////////
|
|
// AGENT PILOT //
|
|
/////////////////
|
|
|
|
|
|
class LLAdvancedAgentPilot : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string command = userdata.asString();
|
|
if ("start playback" == command)
|
|
{
|
|
gAgentPilot.setNumRuns(-1);
|
|
gAgentPilot.startPlayback();
|
|
}
|
|
else if ("stop playback" == command)
|
|
{
|
|
gAgentPilot.stopPlayback();
|
|
}
|
|
else if ("start record" == command)
|
|
{
|
|
gAgentPilot.startRecord();
|
|
}
|
|
else if ("stop record" == command)
|
|
{
|
|
gAgentPilot.stopRecord();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
//////////////////////
|
|
// AGENT PILOT LOOP //
|
|
//////////////////////
|
|
|
|
|
|
class LLAdvancedToggleAgentPilotLoop : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gAgentPilot.setLoop(!gAgentPilot.getLoop());
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckAgentPilotLoop : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gAgentPilot.getLoop();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
/////////////////////////
|
|
// SHOW OBJECT UPDATES //
|
|
/////////////////////////
|
|
|
|
|
|
class LLAdvancedToggleShowObjectUpdates : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gShowObjectUpdates = !(gShowObjectUpdates);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckShowObjectUpdates : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gShowObjectUpdates;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
////////////////////
|
|
// COMPRESS IMAGE //
|
|
////////////////////
|
|
|
|
|
|
class LLAdvancedCompressImage : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_compress_image();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
////////////////////////
|
|
// COMPRESS FILE TEST //
|
|
////////////////////////
|
|
|
|
class LLAdvancedCompressFileTest : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_compress_file_test();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
/////////////////////////
|
|
// SHOW DEBUG SETTINGS //
|
|
/////////////////////////
|
|
|
|
|
|
class LLAdvancedShowDebugSettings : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLFloaterReg::showInstance("settings_debug",userdata);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
////////////////////////
|
|
// VIEW ADMIN OPTIONS //
|
|
////////////////////////
|
|
|
|
class LLAdvancedEnableViewAdminOptions : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// Don't enable in god mode since the admin menu is shown anyway.
|
|
// Only enable if the user has set the appropriate debug setting.
|
|
bool new_value = !gAgent.getAgentAccess().isGodlikeWithoutAdminMenuFakery() && gSavedSettings.getBOOL("AdminMenu");
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedToggleViewAdminOptions : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_admin_override_toggle();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedToggleVisualLeakDetector : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_visual_leak_detector_toggle();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckViewAdminOptions : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = check_admin_override() || gAgent.isGodlike();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
//////////////////
|
|
// ADMIN STATUS //
|
|
//////////////////
|
|
|
|
|
|
class LLAdvancedRequestAdminStatus : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_god_mode();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedLeaveAdminStatus : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_leave_god_mode();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
//////////////////////////
|
|
// Advanced > Debugging //
|
|
//////////////////////////
|
|
|
|
class LLAdvancedForceErrorBreakpoint : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
force_error_breakpoint();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedForceErrorLlerror : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
force_error_llerror();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedForceErrorLlerrorMsg: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
force_error_llerror_msg();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedForceErrorBadMemoryAccess : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
force_error_bad_memory_access();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedForceErrorBadMemoryAccessCoro : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLCoros::instance().launch(
|
|
"AdvancedForceErrorBadMemoryAccessCoro",
|
|
[](){
|
|
// Wait for one mainloop() iteration, letting the enclosing
|
|
// handleEvent() method return.
|
|
llcoro::suspend();
|
|
force_error_bad_memory_access();
|
|
});
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedForceErrorInfiniteLoop : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
force_error_infinite_loop();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedForceErrorSoftwareException : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
force_error_software_exception();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedForceOSException: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
force_error_os_exception();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedForceErrorSoftwareExceptionCoro : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLCoros::instance().launch(
|
|
"AdvancedForceErrorSoftwareExceptionCoro",
|
|
[](){
|
|
// Wait for one mainloop() iteration, letting the enclosing
|
|
// handleEvent() method return.
|
|
llcoro::suspend();
|
|
force_error_software_exception();
|
|
});
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedForceErrorDriverCrash : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
force_error_driver_crash();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// <FS:Ansariel> Wrongly merged back in by LL
|
|
//class LLAdvancedForceErrorCoroutineCrash : public view_listener_t
|
|
//{
|
|
// bool handleEvent(const LLSD& userdata)
|
|
// {
|
|
// force_error_coroutine_crash();
|
|
// return true;
|
|
// }
|
|
//};
|
|
// </FS:Ansariel>
|
|
|
|
class LLAdvancedForceErrorThreadCrash : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
force_error_thread_crash();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedForceErrorDisconnectViewer : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_disconnect_viewer();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
|
|
|
|
class LLAdvancedHandleToggleHackedGodmode : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_toggle_hacked_godmode();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedCheckToggleHackedGodmode : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
check_toggle_hacked_godmode();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedEnableToggleHackedGodmode : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = enable_toggle_hacked_godmode();
|
|
return new_value;
|
|
}
|
|
};
|
|
#endif
|
|
|
|
|
|
//
|
|
////-------------------------------------------------------------------
|
|
//// Advanced menu
|
|
////-------------------------------------------------------------------
|
|
|
|
|
|
//////////////////
|
|
// DEVELOP MENU //
|
|
//////////////////
|
|
|
|
class LLDevelopCheckLoggingLevel : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
U32 level = userdata.asInteger();
|
|
return (static_cast<LLError::ELevel>(level) == LLError::getDefaultLevel());
|
|
}
|
|
};
|
|
|
|
class LLDevelopSetLoggingLevel : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
U32 level = userdata.asInteger();
|
|
LLError::setDefaultLevel(static_cast<LLError::ELevel>(level));
|
|
return true;
|
|
}
|
|
};
|
|
|
|
//////////////////
|
|
// ADMIN MENU //
|
|
//////////////////
|
|
|
|
// Admin > Object
|
|
class LLAdminForceTakeCopy : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
force_take_copy();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdminHandleObjectOwnerSelf : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_object_owner_self();
|
|
return true;
|
|
}
|
|
};
|
|
class LLAdminHandleObjectOwnerPermissive : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_object_owner_permissive();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdminHandleForceDelete : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_force_delete();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdminHandleObjectLock : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_object_lock();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdminHandleObjectAssetIDs: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_object_asset_ids();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
//Admin >Parcel
|
|
class LLAdminHandleForceParcelOwnerToMe: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_force_parcel_owner_to_me();
|
|
return true;
|
|
}
|
|
};
|
|
class LLAdminHandleForceParcelToContent: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_force_parcel_to_content();
|
|
return true;
|
|
}
|
|
};
|
|
class LLAdminHandleClaimPublicLand: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_claim_public_land();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// Admin > Region
|
|
class LLAdminHandleRegionDumpTempAssetData: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_region_dump_temp_asset_data();
|
|
return true;
|
|
}
|
|
};
|
|
//Admin (Top Level)
|
|
|
|
class LLAdminOnSaveState: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLPanelRegionTools::onSaveState(nullptr);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// cleanup_menus()
|
|
//-----------------------------------------------------------------------------
|
|
void cleanup_menus()
|
|
{
|
|
delete gSLMMenuUpdater;
|
|
gSLMMenuUpdater = nullptr;
|
|
|
|
delete gMenuParcelObserver;
|
|
gMenuParcelObserver = NULL;
|
|
|
|
delete gMenuAvatarSelf;
|
|
gMenuAvatarSelf = NULL;
|
|
|
|
delete gMenuAvatarOther;
|
|
gMenuAvatarOther = NULL;
|
|
|
|
delete gMenuObject;
|
|
gMenuObject = NULL;
|
|
|
|
delete gMenuAttachmentSelf;
|
|
gMenuAttachmentSelf = NULL;
|
|
|
|
delete gMenuAttachmentOther;
|
|
gMenuAttachmentOther = NULL;
|
|
|
|
delete gMenuLand;
|
|
gMenuLand = NULL;
|
|
|
|
delete gMenuMuteParticle;
|
|
gMenuMuteParticle = NULL;
|
|
|
|
// <FS:Ansariel> Pie menu
|
|
delete gPieMenuAvatarSelf;
|
|
gPieMenuAvatarSelf = NULL;
|
|
|
|
delete gPieMenuAvatarOther;
|
|
gPieMenuAvatarOther = NULL;
|
|
|
|
delete gPieMenuObject;
|
|
gPieMenuObject = NULL;
|
|
|
|
delete gPieMenuAttachmentSelf;
|
|
gPieMenuAttachmentSelf = NULL;
|
|
|
|
delete gPieMenuAttachmentOther;
|
|
gPieMenuAttachmentOther = NULL;
|
|
|
|
delete gPieMenuLand;
|
|
gPieMenuLand = NULL;
|
|
|
|
delete gPieMenuMuteParticle;
|
|
gPieMenuMuteParticle = NULL;
|
|
// </FS:Ansariel>
|
|
|
|
// <FS:Ansariel> FIRE-7893: Detach function on inspect self toast without function
|
|
delete gMenuInspectSelf;
|
|
gMenuInspectSelf = NULL;
|
|
// </FS:Ansariel>
|
|
|
|
delete gMenuBarView;
|
|
gMenuBarView = NULL;
|
|
|
|
delete gPopupMenuView;
|
|
gPopupMenuView = NULL;
|
|
|
|
delete gMenuHolder;
|
|
gMenuHolder = NULL;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Object pie menu
|
|
//-----------------------------------------------------------------------------
|
|
|
|
// <FS:Ansariel> FIRE-6970/FIRE-6998: Optional permanent derendering of multiple objects
|
|
void derenderObject(bool permanent)
|
|
{
|
|
bool need_save = false;
|
|
LLViewerObject* objp;
|
|
LLSelectMgr* select_mgr = LLSelectMgr::getInstance();
|
|
|
|
while ((objp = select_mgr->getSelection()->getFirstRootObject(true)))
|
|
{
|
|
// if ( (objp) && (gAgentID != objp->getID()) )
|
|
// [RLVa:KB] - Checked: 2012-03-11 (RLVa-1.4.5) | Added: RLVa-1.4.5 | FS-specific
|
|
// Don't allow derendering of own attachments when RLVa is enabled
|
|
if ( (objp) && (gAgentID != objp->getID()) && ((!rlv_handler_t::isEnabled()) || (!objp->isAttachment()) || (!objp->permYouOwner())) )
|
|
// [/RLVa:KB]
|
|
{
|
|
LLUUID id = objp->getID();
|
|
std::string entry_name = "";
|
|
std::string region_name;
|
|
LLAssetType::EType asset_type;
|
|
|
|
if (objp->isAvatar())
|
|
{
|
|
LLNameValue* firstname = objp->getNVPair("FirstName");
|
|
LLNameValue* lastname = objp->getNVPair("LastName");
|
|
entry_name = llformat("%s %s", firstname->getString(), lastname->getString());
|
|
asset_type = LLAssetType::AT_PERSON;
|
|
}
|
|
else
|
|
{
|
|
bool next_object = false;
|
|
LLViewerObject::child_list_t object_children = objp->getChildren();
|
|
for (LLViewerObject::child_list_t::const_iterator it = object_children.begin(); it != object_children.end(); it++)
|
|
{
|
|
LLViewerObject* child = *it;
|
|
if (child->isAvatar() && child->asAvatar()->isSelf())
|
|
{
|
|
if (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT))
|
|
{
|
|
// RLVa: Prevent cheating out of sitting by derendering the object
|
|
select_mgr->deselectObjectOnly(objp);
|
|
next_object = true;
|
|
}
|
|
else
|
|
{
|
|
gAgent.standUp();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (next_object)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
LLSelectNode* nodep = select_mgr->getSelection()->getFirstRootNode();
|
|
if (nodep)
|
|
{
|
|
if (!nodep->mName.empty())
|
|
{
|
|
entry_name = nodep->mName;
|
|
}
|
|
}
|
|
LLViewerRegion* region = objp->getRegion();
|
|
if (region)
|
|
{
|
|
region_name = region->getName();
|
|
}
|
|
asset_type = LLAssetType::AT_OBJECT;
|
|
}
|
|
|
|
FSAssetBlacklist::getInstance()->addNewItemToBlacklist(id, entry_name, region_name, asset_type, permanent, false);
|
|
|
|
if (permanent)
|
|
{
|
|
need_save = true;
|
|
}
|
|
|
|
select_mgr->deselectObjectOnly(objp);
|
|
gObjectList.addDerenderedItem(id, permanent);
|
|
gObjectList.killObject(objp);
|
|
if (LLViewerRegion::sVOCacheCullingEnabled && objp->getRegion())
|
|
{
|
|
objp->getRegion()->killCacheEntry(objp->getLocalID());
|
|
}
|
|
|
|
LLTool* tool = LLToolMgr::getInstance()->getCurrentTool();
|
|
LLViewerObject* tool_editing_object = tool->getEditingObject();
|
|
if (tool_editing_object && tool_editing_object->mID == id)
|
|
{
|
|
tool->stopEditing();
|
|
}
|
|
|
|
}
|
|
else if( (objp) && (gAgentID != objp->getID()) && ((rlv_handler_t::isEnabled()) || (objp->isAttachment()) || (objp->permYouOwner())) )
|
|
{
|
|
select_mgr->deselectObjectOnly(objp);
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (need_save)
|
|
{
|
|
FSAssetBlacklist::getInstance()->saveBlacklist();
|
|
}
|
|
}
|
|
|
|
class LLObjectDerenderPermanent : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
derenderObject(true);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLObjectDerender : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
derenderObject(false);
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:Ansariel>
|
|
|
|
// <FS:CR> FIRE-10082 - Don't enable derendering own attachments when RLVa is enabled
|
|
bool enable_derender_object()
|
|
{
|
|
return (!rlv_handler_t::isEnabled());
|
|
}
|
|
// </FS:CR>
|
|
|
|
class LLEnableEditParticleSource : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLObjectSelectionHandle handle = LLSelectMgr::instance().getSelection();
|
|
|
|
if (handle->getObjectCount() >= 1)
|
|
{
|
|
LLObjectSelection::valid_iterator iter = handle->valid_begin();
|
|
if (iter == handle->valid_end())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
LLSelectNode* node = *iter;
|
|
|
|
if (!node || !node->mPermissions)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (node->mPermissions->getOwner() == gAgentID)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
|
|
class LLEditParticleSource : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (objectp)
|
|
{
|
|
ParticleEditor* particleEditor = LLFloaterReg::showTypedInstance<ParticleEditor>("particle_editor", LLSD(objectp->getID()), TAKE_FOCUS_YES);
|
|
if (particleEditor)
|
|
{
|
|
particleEditor->setObject(objectp);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// <FS:Zi> Texture Refresh
|
|
void destroy_texture(const LLUUID& id) // will be used by the texture refresh functions below
|
|
{
|
|
if (id.isNull() || id == IMG_DEFAULT || FSCommon::isDefaultTexture(id))
|
|
{
|
|
return;
|
|
}
|
|
|
|
LLViewerFetchedTexture* tx = LLViewerTextureManager::getFetchedTexture(id);
|
|
if (tx)
|
|
{
|
|
tx->clearFetchedResults();
|
|
}
|
|
LLAppViewer::getTextureCache()->removeFromCache(id);
|
|
}
|
|
|
|
void handle_object_tex_refresh(LLViewerObject* object, LLSelectNode* node)
|
|
{
|
|
U8 te_count = object->getNumTEs();
|
|
// map from texture ID to list of faces using it
|
|
typedef std::map< LLUUID, std::vector<U8> > map_t;
|
|
map_t faces_per_texture;
|
|
for (U8 i = 0; i < te_count; ++i)
|
|
{
|
|
// "node" will be NULL when invoked from inventory menu,
|
|
// otherwise it will hold the root node of the selection and we
|
|
// need to make sure only to refresh the selected faces
|
|
if (node && !node->isTESelected(i)) continue;
|
|
|
|
LLViewerTexture* img = object->getTEImage(i);
|
|
faces_per_texture[img->getID()].push_back(i);
|
|
|
|
if (object->getTE(i)->getMaterialParams().notNull())
|
|
{
|
|
LLViewerTexture* norm_img = object->getTENormalMap(i);
|
|
faces_per_texture[norm_img->getID()].push_back(i);
|
|
|
|
LLViewerTexture* spec_img = object->getTESpecularMap(i);
|
|
faces_per_texture[spec_img->getID()].push_back(i);
|
|
}
|
|
}
|
|
|
|
map_t::iterator it;
|
|
for (it = faces_per_texture.begin(); it != faces_per_texture.end(); ++it)
|
|
{
|
|
destroy_texture(it->first);
|
|
}
|
|
|
|
// Refresh sculpt texture
|
|
if (object->isSculpted())
|
|
{
|
|
LLSculptParams *sculpt_params = (LLSculptParams *)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
|
|
if (sculpt_params)
|
|
{
|
|
LLUUID sculpt_uuid = sculpt_params->getSculptTexture();
|
|
|
|
LLViewerFetchedTexture* tx = LLViewerTextureManager::getFetchedTexture(sculpt_uuid);
|
|
if (tx)
|
|
{
|
|
S32 num_volumes = tx->getNumVolumes(LLRender::SCULPT_TEX);
|
|
const LLViewerTexture::ll_volume_list_t* pVolumeList = tx->getVolumeList(LLRender::SCULPT_TEX);
|
|
|
|
destroy_texture(sculpt_uuid);
|
|
|
|
for (S32 idxVolume = 0; idxVolume < num_volumes; ++idxVolume)
|
|
{
|
|
LLVOVolume* pVolume = pVolumeList->at(idxVolume);
|
|
if (pVolume)
|
|
{
|
|
pVolume->notifyMeshLoaded();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class LLObjectTexRefresh : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// partly copied from the texture info code in handle_selected_texture_info()
|
|
for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin();
|
|
iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++)
|
|
{
|
|
LLSelectNode* node = *iter;
|
|
handle_object_tex_refresh(node->getObject(),node);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
void avatar_tex_refresh(LLVOAvatar* avatar)
|
|
{
|
|
// I bet this can be done more elegantly, but this is just straightforward
|
|
destroy_texture(avatar->getTE(TEX_HEAD_BAKED)->getID());
|
|
destroy_texture(avatar->getTE(TEX_UPPER_BAKED)->getID());
|
|
destroy_texture(avatar->getTE(TEX_LOWER_BAKED)->getID());
|
|
destroy_texture(avatar->getTE(TEX_EYES_BAKED)->getID());
|
|
destroy_texture(avatar->getTE(TEX_SKIRT_BAKED)->getID());
|
|
destroy_texture(avatar->getTE(TEX_HAIR_BAKED)->getID());
|
|
LLAvatarPropertiesProcessor::getInstance()->sendAvatarTexturesRequest(avatar->getID());
|
|
}
|
|
|
|
class LLAvatarTexRefresh : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
|
|
if (avatar)
|
|
{
|
|
avatar_tex_refresh(avatar);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:Zi> Texture Refresh
|
|
|
|
class LLObjectReportAbuse : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (objectp)
|
|
{
|
|
LLFloaterReporter::showFromObject(objectp->getID());
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// Enabled it you clicked an object
|
|
class LLObjectEnableReportAbuse : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLSelectMgr::getInstance()->getSelection()->getObjectCount() != 0;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
void handle_object_touch()
|
|
{
|
|
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (!object) return;
|
|
|
|
LLPickInfo pick = LLToolPie::getInstance()->getPick();
|
|
|
|
// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Modified: RLVa-1.1.0l
|
|
// NOTE: fallback code since we really shouldn't be getting an active selection if we can't touch this
|
|
if ( (RlvActions::isRlvEnabled()) && (!RlvActions::canTouch(object, pick.mObjectOffset)) )
|
|
{
|
|
RLV_ASSERT(false);
|
|
return;
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
// *NOTE: Hope the packets arrive safely and in order or else
|
|
// there will be some problems.
|
|
// *TODO: Just fix this bad assumption.
|
|
send_ObjectGrab_message(object, pick, LLVector3::zero);
|
|
send_ObjectDeGrab_message(object, pick);
|
|
}
|
|
|
|
void handle_object_show_original()
|
|
{
|
|
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (!object)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LLViewerObject *parent = (LLViewerObject*)object->getParent();
|
|
while (parent)
|
|
{
|
|
if(parent->isAvatar())
|
|
{
|
|
break;
|
|
}
|
|
object = parent;
|
|
parent = (LLViewerObject*)parent->getParent();
|
|
}
|
|
|
|
if (!object || object->isAvatar())
|
|
{
|
|
return;
|
|
}
|
|
|
|
show_item_original(object->getAttachmentItemID());
|
|
}
|
|
|
|
// <FS:Ansariel> Disable if prevented by RLVa
|
|
bool enable_object_show_original()
|
|
{
|
|
return !RlvActions::hasBehaviour(RLV_BHVR_SHOWINV);
|
|
}
|
|
// </FS:Ansariel>
|
|
|
|
static void init_default_item_label(LLUICtrl* ctrl)
|
|
{
|
|
const std::string& item_name = ctrl->getName();
|
|
boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
|
|
if (it == sDefaultItemLabels.end())
|
|
{
|
|
// *NOTE: This will not work for items of type LLMenuItemCheckGL because they return boolean value
|
|
// (doesn't seem to matter much ATM).
|
|
LLStringExplicit default_label = ctrl->getValue().asString();
|
|
if (!default_label.empty())
|
|
{
|
|
sDefaultItemLabels.insert(std::pair<std::string, LLStringExplicit>(item_name, default_label));
|
|
}
|
|
}
|
|
}
|
|
|
|
static LLStringExplicit get_default_item_label(const std::string& item_name)
|
|
{
|
|
LLStringExplicit res("");
|
|
boost::unordered_map<std::string, LLStringExplicit>::iterator it = sDefaultItemLabels.find(item_name);
|
|
if (it != sDefaultItemLabels.end())
|
|
{
|
|
res = it->second;
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
|
|
bool enable_object_touch(LLUICtrl* ctrl)
|
|
{
|
|
bool new_value = false;
|
|
LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (obj)
|
|
{
|
|
LLViewerObject* parent = (LLViewerObject*)obj->getParent();
|
|
new_value = obj->flagHandleTouch() || (parent && parent->flagHandleTouch());
|
|
}
|
|
|
|
// [RLVa:KB] - Checked: 2010-11-12 (RLVa-1.2.1g) | Added: RLVa-1.2.1g
|
|
if ( (RlvActions::isRlvEnabled()) && (new_value) )
|
|
{
|
|
// RELEASE-RLVa: [RLVa-1.2.1] Make sure this stays in sync with handle_object_touch()
|
|
new_value = RlvActions::canTouch(obj, LLToolPie::getInstance()->getPick().mObjectOffset);
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
init_default_item_label(ctrl);
|
|
|
|
// Update label based on the node touch name if available.
|
|
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
|
|
if (node && node->mValid && !node->mTouchName.empty())
|
|
{
|
|
ctrl->setValue(node->mTouchName);
|
|
}
|
|
else
|
|
{
|
|
ctrl->setValue(get_default_item_label(ctrl->getName()));
|
|
}
|
|
|
|
return new_value;
|
|
};
|
|
|
|
//void label_touch(std::string& label, void*)
|
|
//{
|
|
// LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
|
|
// if (node && node->mValid && !node->mTouchName.empty())
|
|
// {
|
|
// label.assign(node->mTouchName);
|
|
// }
|
|
// else
|
|
// {
|
|
// label.assign("Touch");
|
|
// }
|
|
//}
|
|
|
|
void handle_object_open()
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-04-11 (RLVa-1.2.0e) | Added: RLVa-1.2.0e
|
|
if (enable_object_open())
|
|
LLFloaterReg::showInstance("openobject");
|
|
// [/RLVa:KB]
|
|
// LLFloaterReg::showInstance("openobject");
|
|
}
|
|
|
|
bool enable_object_inspect()
|
|
{
|
|
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
|
|
LLViewerObject* selected_objectp = selection->getFirstRootObject();
|
|
return selected_objectp != NULL;
|
|
}
|
|
|
|
struct LLSelectedTEGetmatIdAndPermissions : public LLSelectedTEFunctor
|
|
{
|
|
LLSelectedTEGetmatIdAndPermissions()
|
|
: mCanCopy(true)
|
|
, mCanModify(true)
|
|
, mCanTransfer(true)
|
|
, mHasNonPbrFaces(false)
|
|
{}
|
|
bool apply(LLViewerObject* objectp, S32 te_index)
|
|
{
|
|
mCanCopy &= (bool)objectp->permCopy();
|
|
mCanTransfer &= (bool)objectp->permTransfer();
|
|
mCanModify &= (bool)objectp->permModify();
|
|
LLUUID mat_id = objectp->getRenderMaterialID(te_index);
|
|
if (mat_id.notNull())
|
|
{
|
|
mMaterialId = mat_id;
|
|
}
|
|
else
|
|
{
|
|
mHasNonPbrFaces = true;
|
|
}
|
|
return true;
|
|
}
|
|
bool mCanCopy;
|
|
bool mCanModify;
|
|
bool mCanTransfer;
|
|
bool mHasNonPbrFaces;
|
|
LLUUID mMaterialId;
|
|
};
|
|
|
|
bool enable_object_edit_gltf_material()
|
|
{
|
|
if (!LLMaterialEditor::capabilitiesAvailable())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
LLSelectedTEGetmatIdAndPermissions func;
|
|
LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func);
|
|
return func.mCanModify && !func.mHasNonPbrFaces;
|
|
}
|
|
|
|
bool enable_object_open()
|
|
{
|
|
// Look for contents in root object, which is all the LLFloaterOpenObject
|
|
// understands.
|
|
LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (!obj) return false;
|
|
|
|
LLViewerObject* root = obj->getRootEdit();
|
|
if (!root) return false;
|
|
|
|
return root->allowOpen();
|
|
}
|
|
|
|
|
|
class LLViewJoystickFlycam : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_toggle_flycam();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLViewCheckJoystickFlycam : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLViewerJoystick::getInstance()->getOverrideCamera();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
void handle_toggle_flycam()
|
|
{
|
|
LLViewerJoystick::getInstance()->toggleFlycam();
|
|
}
|
|
|
|
class LLObjectBuild : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
|
|
{
|
|
// zoom in if we're looking at the avatar
|
|
gAgentCamera.setFocusOnAvatar(false, ANIMATE);
|
|
gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
|
|
gAgentCamera.cameraZoomIn(0.666f);
|
|
gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
|
|
gViewerWindow->moveCursorToCenter();
|
|
}
|
|
else if ( gSavedSettings.getBOOL("EditCameraMovement") )
|
|
{
|
|
gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
|
|
gViewerWindow->moveCursorToCenter();
|
|
}
|
|
|
|
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
|
|
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );
|
|
|
|
// Could be first use
|
|
//LLFirstUse::useBuild();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
void update_camera()
|
|
{
|
|
LLViewerParcelMgr::getInstance()->deselectLand();
|
|
|
|
if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit())
|
|
{
|
|
LLFloaterTools::sPreviousFocusOnAvatar = true;
|
|
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
|
|
|
|
if (selection->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement"))
|
|
{
|
|
// always freeze camera in space, even if camera doesn't move
|
|
// so, for example, follow cam scripts can't affect you when in build mode
|
|
gAgentCamera.setFocusGlobal(gAgentCamera.calcFocusPositionTargetGlobal(), LLUUID::null);
|
|
gAgentCamera.setFocusOnAvatar(false, ANIMATE);
|
|
}
|
|
else
|
|
{
|
|
gAgentCamera.setFocusOnAvatar(false, ANIMATE);
|
|
LLViewerObject* selected_objectp = selection->getFirstRootObject();
|
|
if (selected_objectp)
|
|
{
|
|
// zoom in on object center instead of where we clicked, as we need to see the manipulator handles
|
|
gAgentCamera.setFocusGlobal(selected_objectp->getPositionGlobal(), selected_objectp->getID());
|
|
gAgentCamera.cameraZoomIn(0.666f);
|
|
gAgentCamera.cameraOrbitOver(30.f * DEG_TO_RAD);
|
|
gViewerWindow->moveCursorToCenter();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void handle_object_edit()
|
|
{
|
|
update_camera();
|
|
|
|
LLFloaterReg::showInstance("build");
|
|
|
|
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
|
|
gFloaterTools->setEditTool( LLToolCompTranslate::getInstance() );
|
|
|
|
LLViewerJoystick::getInstance()->moveObjects(true);
|
|
LLViewerJoystick::getInstance()->setNeedsReset(true);
|
|
|
|
// Could be first use
|
|
//LLFirstUse::useBuild();
|
|
return;
|
|
}
|
|
|
|
void handle_object_edit_gltf_material()
|
|
{
|
|
if (!LLFloaterReg::instanceVisible("build"))
|
|
{
|
|
handle_object_edit(); // does update_camera();
|
|
}
|
|
else
|
|
{
|
|
update_camera();
|
|
|
|
LLViewerJoystick::getInstance()->moveObjects(true);
|
|
LLViewerJoystick::getInstance()->setNeedsReset(true);
|
|
}
|
|
|
|
LLMaterialEditor::loadLive();
|
|
}
|
|
|
|
void handle_attachment_edit(const LLUUID& inv_item_id)
|
|
{
|
|
if (isAgentAvatarValid())
|
|
{
|
|
if (LLViewerObject* attached_obj = gAgentAvatarp->getWornAttachment(inv_item_id))
|
|
{
|
|
LLSelectMgr::getInstance()->deselectAll();
|
|
LLSelectMgr::getInstance()->selectObjectAndFamily(attached_obj);
|
|
|
|
handle_object_edit();
|
|
}
|
|
}
|
|
}
|
|
|
|
void handle_attachment_touch(const LLUUID& inv_item_id)
|
|
{
|
|
if ( (isAgentAvatarValid()) && (enable_attachment_touch(inv_item_id)) )
|
|
{
|
|
if (LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id)))
|
|
{
|
|
LLSelectMgr::getInstance()->deselectAll();
|
|
|
|
LLObjectSelectionHandle sel = LLSelectMgr::getInstance()->selectObjectAndFamily(attach_obj);
|
|
if (!LLToolMgr::getInstance()->inBuildMode())
|
|
{
|
|
struct SetTransient : public LLSelectedNodeFunctor
|
|
{
|
|
bool apply(LLSelectNode* node)
|
|
{
|
|
node->setTransient(true);
|
|
return true;
|
|
}
|
|
} f;
|
|
sel->applyToNodes(&f);
|
|
}
|
|
|
|
handle_object_touch();
|
|
}
|
|
}
|
|
}
|
|
|
|
bool enable_attachment_touch(const LLUUID& inv_item_id)
|
|
{
|
|
if (isAgentAvatarValid())
|
|
{
|
|
const LLViewerObject* attach_obj = gAgentAvatarp->getWornAttachment(gInventory.getLinkedItemID(inv_item_id));
|
|
// [RLVa:KB] - @touch*
|
|
return (attach_obj) && (attach_obj->flagHandleTouch()) && (!RlvActions::isRlvEnabled() || RlvActions::canTouch(attach_obj));
|
|
// [/RLVa:KB]
|
|
// return (attach_obj) && (attach_obj->flagHandleTouch());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void handle_object_inspect()
|
|
{
|
|
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
|
|
LLViewerObject* selected_objectp = selection->getFirstRootObject();
|
|
if (selected_objectp)
|
|
{
|
|
LLFloaterReg::showInstance("task_properties");
|
|
}
|
|
|
|
/*
|
|
// Old floater properties
|
|
LLFloaterReg::showInstance("inspect", LLSD());
|
|
*/
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Land pie menu
|
|
//---------------------------------------------------------------------------
|
|
class LLLandBuild : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLViewerParcelMgr::getInstance()->deselectLand();
|
|
|
|
if (gAgentCamera.getFocusOnAvatar() && !LLToolMgr::getInstance()->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
|
|
{
|
|
// zoom in if we're looking at the avatar
|
|
gAgentCamera.setFocusOnAvatar(false, ANIMATE);
|
|
gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
|
|
gAgentCamera.cameraZoomIn(0.666f);
|
|
gAgentCamera.cameraOrbitOver( 30.f * DEG_TO_RAD );
|
|
gViewerWindow->moveCursorToCenter();
|
|
}
|
|
else if ( gSavedSettings.getBOOL("EditCameraMovement") )
|
|
{
|
|
// otherwise just move focus
|
|
gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
|
|
gViewerWindow->moveCursorToCenter();
|
|
}
|
|
|
|
|
|
LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
|
|
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolCompCreate::getInstance() );
|
|
|
|
// Could be first use
|
|
//LLFirstUse::useBuild();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLLandBuyPass : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLPanelLandGeneral::onClickBuyPass((void *)false);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLLandEnableBuyPass : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLPanelLandGeneral::enableBuyPass(nullptr);
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
bool enable_object_edit()
|
|
{
|
|
if (!isAgentAvatarValid()) return false;
|
|
|
|
// *HACK: The new "prelude" Help Islands have a build sandbox area,
|
|
// so users need the Edit and Create pie menu options when they are
|
|
// there. Eventually this needs to be replaced with code that only
|
|
// lets you edit objects if you have permission to do so (edit perms,
|
|
// group edit, god). See also lltoolbar.cpp. JC
|
|
bool enable = false;
|
|
if (gAgent.inPrelude())
|
|
{
|
|
enable = LLViewerParcelMgr::getInstance()->allowAgentBuild()
|
|
|| LLSelectMgr::getInstance()->getSelection()->isAttachment();
|
|
}
|
|
else if (LLSelectMgr::getInstance()->selectGetAllValidAndObjectsFound())
|
|
{
|
|
// [RLVa:KB] - @edit*
|
|
if (RlvActions::isRlvEnabled() && !RlvActions::canEdit(ERlvCheckType::All))
|
|
{
|
|
LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection();
|
|
RlvSelectIsEditable f;
|
|
enable = (hSel.notNull()) && (!hSel->getFirstRootNode(&f, true));
|
|
}
|
|
else
|
|
{
|
|
enable = true;
|
|
}
|
|
// [/RLVa:KB]
|
|
// enable = true;
|
|
}
|
|
|
|
return enable;
|
|
}
|
|
|
|
bool enable_mute_particle()
|
|
{
|
|
const LLPickInfo& pick = LLToolPie::getInstance()->getPick();
|
|
|
|
return pick.mParticleOwnerID != LLUUID::null && pick.mParticleOwnerID != gAgent.getID();
|
|
}
|
|
|
|
bool enable_object_select_in_pathfinding_linksets()
|
|
{
|
|
return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetEditableLinksets();
|
|
}
|
|
|
|
bool visible_object_select_in_pathfinding_linksets()
|
|
{
|
|
return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion();
|
|
}
|
|
|
|
bool enable_object_select_in_pathfinding_characters()
|
|
{
|
|
return LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLSelectMgr::getInstance()->selectGetViewableCharacters();
|
|
}
|
|
|
|
bool enable_os_exception()
|
|
{
|
|
#if LL_DARWIN
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
|
|
|
|
bool enable_gltf()
|
|
{
|
|
static LLCachedControl<bool> enablegltf(gSavedSettings, "GLTFEnabled", false);
|
|
static LLCachedControl<bool> can_use(gSavedSettings, "RenderCanUseGLTFPBROpaqueShaders", true);
|
|
|
|
return enablegltf && can_use;
|
|
}
|
|
|
|
bool enable_gltf_save_as()
|
|
{
|
|
if (enable_gltf())
|
|
{
|
|
LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
|
|
if (obj)
|
|
{
|
|
if (obj->mGLTFAsset && obj->mGLTFAsset->isLocalPreview())
|
|
{
|
|
return true;
|
|
}
|
|
|
|
LLPermissions* permissions = LLSelectMgr::getInstance()->findObjectPermissions(obj);
|
|
if (permissions)
|
|
{
|
|
return permissions->allowExportBy(gAgent.getID());
|
|
}
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool enable_gltf_upload()
|
|
{
|
|
return enable_gltf_save_as();
|
|
}
|
|
|
|
bool enable_terrain_local_paintmap()
|
|
{
|
|
static LLCachedControl<bool> can_use_shaders(gSavedSettings, "RenderCanUseTerrainBakeShaders", true);
|
|
return can_use_shaders;
|
|
}
|
|
|
|
class LLSelfRemoveAllAttachments : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLAppearanceMgr::instance().removeAllAttachmentsFromAvatar();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLSelfEnableRemoveAllAttachments : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = false;
|
|
if (isAgentAvatarValid())
|
|
{
|
|
for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
|
|
iter != gAgentAvatarp->mAttachmentPoints.end(); )
|
|
{
|
|
LLVOAvatar::attachment_map_t::iterator curiter = iter++;
|
|
LLViewerJointAttachment* attachment = curiter->second;
|
|
// if (attachment->getNumObjects() > 0)
|
|
// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
|
|
if ( (attachment->getNumObjects() > 0) && ((!rlv_handler_t::isEnabled()) || (gRlvAttachmentLocks.canDetach(attachment))) )
|
|
// [/RLVa:KB]
|
|
{
|
|
new_value = true;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
bool enable_has_attachments()
|
|
{
|
|
return false;
|
|
}
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Avatar pie menu
|
|
//---------------------------------------------------------------------------
|
|
//void handle_follow(void *userdata)
|
|
//{
|
|
// // follow a given avatar by ID
|
|
// LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
// if (objectp)
|
|
// {
|
|
// gAgent.startFollowPilot(objectp->getID());
|
|
// }
|
|
//}
|
|
|
|
bool enable_object_mute()
|
|
{
|
|
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (!object) return false;
|
|
|
|
LLVOAvatar* avatar = find_avatar_from_object(object);
|
|
if (avatar)
|
|
{
|
|
// It's an avatar
|
|
LLNameValue *lastname = avatar->getNVPair("LastName");
|
|
bool is_linden =
|
|
lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden");
|
|
bool is_self = avatar->isSelf();
|
|
// return !is_linden && !is_self;
|
|
// [RLVa:KB] - Checked: RLVa-1.2.1
|
|
// return !is_linden && !is_self && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID()));
|
|
// [/RLVa:KB]
|
|
|
|
// <FS:Zi> Make enable/disable of block/unblock menu items work for avatars
|
|
if(is_linden || is_self)
|
|
return false;
|
|
|
|
if (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID()))
|
|
return false;
|
|
|
|
LLNameValue *firstname = avatar->getNVPair("FirstName");
|
|
|
|
std::string name;
|
|
if (firstname && lastname)
|
|
{
|
|
name = LLCacheName::buildFullName(
|
|
firstname->getString(), lastname->getString());
|
|
}
|
|
|
|
LLMute mute(avatar->getID(),name,LLMute::AGENT);
|
|
return !LLMuteList::getInstance()->isMuted(mute.mID);
|
|
// </FS:Zi>
|
|
}
|
|
else
|
|
{
|
|
// Just a regular object
|
|
return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) &&
|
|
!LLMuteList::getInstance()->isMuted(object->getID());
|
|
}
|
|
}
|
|
|
|
bool enable_object_unmute()
|
|
{
|
|
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (!object) return false;
|
|
|
|
LLVOAvatar* avatar = find_avatar_from_object(object);
|
|
if (avatar)
|
|
{
|
|
// It's an avatar
|
|
LLNameValue *lastname = avatar->getNVPair("LastName");
|
|
bool is_linden =
|
|
lastname && !LLStringUtil::compareStrings(lastname->getString(), "Linden");
|
|
bool is_self = avatar->isSelf();
|
|
// <FS:Zi> Make enable/disable of block/unblock menu items work for avatars
|
|
// return !is_linden && !is_self;
|
|
if(is_linden || is_self)
|
|
return false;
|
|
|
|
LLNameValue *firstname = avatar->getNVPair("FirstName");
|
|
std::string name;
|
|
if (firstname && lastname)
|
|
{
|
|
name = LLCacheName::buildFullName(
|
|
firstname->getString(), lastname->getString());
|
|
}
|
|
|
|
LLMute mute(avatar->getID(),name,LLMute::AGENT);
|
|
return LLMuteList::getInstance()->isMuted(mute.mID);
|
|
// </FS:Zi>
|
|
}
|
|
else
|
|
{
|
|
// Just a regular object
|
|
return LLSelectMgr::getInstance()->getSelection()->contains( object, SELECT_ALL_TES ) &&
|
|
LLMuteList::getInstance()->isMuted(object->getID());;
|
|
}
|
|
}
|
|
|
|
// <FS:Ansariel> Avatar render more check for pie menu
|
|
bool check_avatar_render_mode(U32 mode)
|
|
{
|
|
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (!object) return false;
|
|
|
|
LLVOAvatar* avatar = find_avatar_from_object(object);
|
|
if (!avatar) return false;
|
|
|
|
switch (mode)
|
|
{
|
|
case 0:
|
|
return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) == LLVOAvatar::AV_RENDER_NORMALLY;
|
|
// return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_RENDER_NORMALLY);
|
|
case 1:
|
|
return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) == LLVOAvatar::AV_DO_NOT_RENDER;
|
|
// return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);
|
|
case 2:
|
|
return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) == LLVOAvatar::AV_ALWAYS_RENDER;
|
|
// return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
|
|
case 4:
|
|
return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) != LLVOAvatar::AV_RENDER_NORMALLY;
|
|
// return FSAvatarRenderPersistence::instance().getAvatarRenderSettings(avatar->getID()) == LLVOAvatar::AV_RENDER_NORMALLY;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
// </FS:Ansariel>
|
|
|
|
// 0 = normal, 1 = always, 2 = never
|
|
class LLAvatarCheckImpostorMode : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// <FS:Ansariel> Avatar render more check for pie menu
|
|
//LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
//if (!object) return false;
|
|
|
|
//LLVOAvatar* avatar = find_avatar_from_object(object);
|
|
//if (!avatar) return false;
|
|
//
|
|
//U32 mode = userdata.asInteger();
|
|
//switch (mode)
|
|
//{
|
|
// case 0:
|
|
// return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_RENDER_NORMALLY);
|
|
// case 1:
|
|
// return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);
|
|
// case 2:
|
|
// return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
|
|
// case 4:
|
|
// return (avatar->getVisualMuteSettings() != LLVOAvatar::AV_RENDER_NORMALLY);
|
|
// default:
|
|
// return false;
|
|
//}
|
|
return check_avatar_render_mode(userdata.asInteger());
|
|
// </FS:Ansariel>
|
|
} // handleEvent()
|
|
};
|
|
|
|
// 0 = normal, 1 = always, 2 = never
|
|
class LLAvatarSetImpostorMode : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (!object) return false;
|
|
|
|
LLVOAvatar* avatar = find_avatar_from_object(object);
|
|
if (!avatar) return false;
|
|
|
|
U32 mode = userdata.asInteger();
|
|
switch (mode)
|
|
{
|
|
case 0:
|
|
avatar->setVisualMuteSettings(LLVOAvatar::AV_RENDER_NORMALLY);
|
|
break;
|
|
case 1:
|
|
avatar->setVisualMuteSettings(LLVOAvatar::AV_DO_NOT_RENDER);
|
|
break;
|
|
case 2:
|
|
avatar->setVisualMuteSettings(LLVOAvatar::AV_ALWAYS_RENDER);
|
|
break;
|
|
default:
|
|
return false;
|
|
}
|
|
|
|
LLVOAvatar::cullAvatarsByPixelArea();
|
|
return true;
|
|
} // handleEvent()
|
|
};
|
|
|
|
|
|
class LLObjectMute : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (!object) return true;
|
|
|
|
LLUUID id;
|
|
std::string name;
|
|
LLMute::EType type;
|
|
LLVOAvatar* avatar = find_avatar_from_object(object);
|
|
if (avatar)
|
|
{
|
|
id = avatar->getID();
|
|
// [RLVa:KB] - Checked: RLVa-1.0.0
|
|
if (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, id))
|
|
return true;
|
|
// [/RLVa:KB]
|
|
|
|
avatar->mNeedsImpostorUpdate = true;
|
|
avatar->mLastImpostorUpdateReason = 9;
|
|
|
|
|
|
LLNameValue *firstname = avatar->getNVPair("FirstName");
|
|
LLNameValue *lastname = avatar->getNVPair("LastName");
|
|
if (firstname && lastname)
|
|
{
|
|
name = LLCacheName::buildFullName(
|
|
firstname->getString(), lastname->getString());
|
|
}
|
|
|
|
type = LLMute::AGENT;
|
|
}
|
|
else
|
|
{
|
|
// it's an object
|
|
id = object->getID();
|
|
|
|
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
|
|
if (node)
|
|
{
|
|
name = node->mName;
|
|
}
|
|
|
|
type = LLMute::OBJECT;
|
|
}
|
|
|
|
LLMute mute(id, name, type);
|
|
if (LLMuteList::getInstance()->isMuted(mute.mID))
|
|
{
|
|
LLMuteList::getInstance()->remove(mute);
|
|
}
|
|
else
|
|
{
|
|
LLMuteList::getInstance()->add(mute);
|
|
LLPanelBlockedList::showPanelAndSelect(mute.mID);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
bool handle_go_to()
|
|
{
|
|
// try simulator autopilot
|
|
std::vector<std::string> strings;
|
|
std::string val;
|
|
LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal;
|
|
val = llformat("%g", pos.mdV[VX]);
|
|
strings.push_back(val);
|
|
val = llformat("%g", pos.mdV[VY]);
|
|
strings.push_back(val);
|
|
val = llformat("%g", pos.mdV[VZ]);
|
|
strings.push_back(val);
|
|
send_generic_message("autopilot", strings);
|
|
|
|
LLViewerParcelMgr::getInstance()->deselectLand();
|
|
|
|
if (isAgentAvatarValid() && !gSavedSettings.getBOOL("AutoPilotLocksCamera"))
|
|
{
|
|
gAgentCamera.setFocusGlobal(gAgentCamera.getFocusTargetGlobal(), gAgentAvatarp->getID());
|
|
}
|
|
else
|
|
{
|
|
// Snap camera back to behind avatar
|
|
gAgentCamera.setFocusOnAvatar(true, ANIMATE);
|
|
}
|
|
|
|
// Could be first use
|
|
//LLFirstUse::useGoTo();
|
|
return true;
|
|
}
|
|
|
|
class LLGoToObject : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return handle_go_to();
|
|
}
|
|
};
|
|
|
|
class LLAvatarReportAbuse : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
|
if(avatar)
|
|
{
|
|
LLFloaterReporter::showFromObject(avatar->getID());
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
//---------------------------------------------------------------------------
|
|
// Parcel freeze, eject, etc.
|
|
//---------------------------------------------------------------------------
|
|
//bool callback_freeze(const LLSD& notification, const LLSD& response)
|
|
//{
|
|
// LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
|
|
// S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
//
|
|
// if (0 == option || 1 == option)
|
|
// {
|
|
// U32 flags = 0x0;
|
|
// if (1 == option)
|
|
// {
|
|
// // unfreeze
|
|
// flags |= 0x1;
|
|
// }
|
|
//
|
|
// LLMessageSystem* msg = gMessageSystem;
|
|
// LLViewerObject* avatar = gObjectList.findObject(avatar_id);
|
|
//
|
|
// if (avatar)
|
|
// {
|
|
// msg->newMessage("FreezeUser");
|
|
// msg->nextBlock("AgentData");
|
|
// msg->addUUID("AgentID", gAgent.getID());
|
|
// msg->addUUID("SessionID", gAgent.getSessionID());
|
|
// msg->nextBlock("Data");
|
|
// msg->addUUID("TargetID", avatar_id );
|
|
// msg->addU32("Flags", flags );
|
|
// msg->sendReliable( avatar->getRegion()->getHost() );
|
|
// }
|
|
// }
|
|
// return false;
|
|
//}
|
|
|
|
|
|
void handle_avatar_freeze(const LLSD& avatar_id)
|
|
{
|
|
// [SL:KB] - Patch: UI-AvatarNearbyActions | Checked: 2011-05-13 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
|
|
// Use avatar_id if available, otherwise default to right-click avatar
|
|
LLUUID idAgent = avatar_id.asUUID();
|
|
if (idAgent.isNull())
|
|
{
|
|
/*const*/ LLVOAvatar* pAvatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
|
|
if (pAvatar)
|
|
idAgent = pAvatar->getID();
|
|
}
|
|
if (idAgent.notNull())
|
|
{
|
|
LLAvatarActions::landFreeze(idAgent);
|
|
}
|
|
// [/SL:KB]
|
|
// // Use avatar_id if available, otherwise default to right-click avatar
|
|
// LLVOAvatar* avatar = NULL;
|
|
// if (avatar_id.asUUID().notNull())
|
|
// {
|
|
// avatar = find_avatar_from_object(avatar_id.asUUID());
|
|
// }
|
|
// else
|
|
// {
|
|
// avatar = find_avatar_from_object(
|
|
// LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
|
|
// }
|
|
//
|
|
// if( avatar )
|
|
// {
|
|
// std::string fullname = avatar->getFullname();
|
|
// LLSD payload;
|
|
// payload["avatar_id"] = avatar->getID();
|
|
//
|
|
// if (!fullname.empty())
|
|
// {
|
|
// LLSD args;
|
|
// args["AVATAR_NAME"] = fullname;
|
|
// [RLVa:KB] - Checked: RLVa-1.0.0
|
|
// args["AVATAR_NAME"] = (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) ? fullname : RlvStrings::getAnonym(fullname);
|
|
// [/RLVa:KB]
|
|
// LLNotificationsUtil::add("FreezeAvatarFullname",
|
|
// args,
|
|
// payload,
|
|
// callback_freeze);
|
|
// }
|
|
// else
|
|
// {
|
|
// LLNotificationsUtil::add("FreezeAvatar",
|
|
// LLSD(),
|
|
// payload,
|
|
// callback_freeze);
|
|
// }
|
|
// }
|
|
}
|
|
|
|
class LLAvatarVisibleDebug : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return gAgent.isGodlike();
|
|
}
|
|
};
|
|
|
|
class LLAvatarDebug : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
|
if( avatar )
|
|
{
|
|
if (avatar->isSelf())
|
|
{
|
|
((LLVOAvatarSelf *)avatar)->dumpLocalTextures();
|
|
}
|
|
LL_INFOS() << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << LL_ENDL;
|
|
// <FS:Ansariel> Disable message - spawns error "generic request failed"
|
|
//std::vector<std::string> strings;
|
|
//strings.push_back(avatar->getID().asString());
|
|
//LLUUID invoice;
|
|
//send_generic_message("dumptempassetdata", strings, invoice);
|
|
// </FS:Ansariel>
|
|
LLFloaterReg::showInstance( "avatar_textures", LLSD(avatar->getID()) );
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
//bool callback_eject(const LLSD& notification, const LLSD& response)
|
|
//{
|
|
// S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
// if (2 == option)
|
|
// {
|
|
// // Cancel button.
|
|
// return false;
|
|
// }
|
|
// LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
|
|
// bool ban_enabled = notification["payload"]["ban_enabled"].asBoolean();
|
|
//
|
|
// if (0 == option)
|
|
// {
|
|
// // Eject button
|
|
// LLMessageSystem* msg = gMessageSystem;
|
|
// LLViewerObject* avatar = gObjectList.findObject(avatar_id);
|
|
//
|
|
// if (avatar)
|
|
// {
|
|
// U32 flags = 0x0;
|
|
// msg->newMessage("EjectUser");
|
|
// msg->nextBlock("AgentData");
|
|
// msg->addUUID("AgentID", gAgent.getID() );
|
|
// msg->addUUID("SessionID", gAgent.getSessionID() );
|
|
// msg->nextBlock("Data");
|
|
// msg->addUUID("TargetID", avatar_id );
|
|
// msg->addU32("Flags", flags );
|
|
// msg->sendReliable( avatar->getRegion()->getHost() );
|
|
// }
|
|
// }
|
|
// else if (ban_enabled)
|
|
// {
|
|
// // This is tricky. It is similar to say if it is not an 'Eject' button,
|
|
// // and it is also not an 'Cancle' button, and ban_enabled==ture,
|
|
// // it should be the 'Eject and Ban' button.
|
|
// LLMessageSystem* msg = gMessageSystem;
|
|
// LLViewerObject* avatar = gObjectList.findObject(avatar_id);
|
|
//
|
|
// if (avatar)
|
|
// {
|
|
// U32 flags = 0x1;
|
|
// msg->newMessage("EjectUser");
|
|
// msg->nextBlock("AgentData");
|
|
// msg->addUUID("AgentID", gAgent.getID() );
|
|
// msg->addUUID("SessionID", gAgent.getSessionID() );
|
|
// msg->nextBlock("Data");
|
|
// msg->addUUID("TargetID", avatar_id );
|
|
// msg->addU32("Flags", flags );
|
|
// msg->sendReliable( avatar->getRegion()->getHost() );
|
|
// }
|
|
// }
|
|
// return false;
|
|
//}
|
|
|
|
void handle_avatar_eject(const LLSD& avatar_id)
|
|
{
|
|
// [SL:KB] - Patch: UI-AvatarNearbyActions | Checked: 2011-05-13 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
|
|
// Use avatar_id if available, otherwise default to right-click avatar
|
|
LLUUID idAgent = avatar_id.asUUID();
|
|
if (idAgent.isNull())
|
|
{
|
|
/*const*/ LLVOAvatar* pAvatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
|
|
if (pAvatar)
|
|
idAgent = pAvatar->getID();
|
|
}
|
|
if (idAgent.notNull())
|
|
{
|
|
LLAvatarActions::landEject(idAgent);
|
|
}
|
|
// [/SL:KB]
|
|
// // Use avatar_id if available, otherwise default to right-click avatar
|
|
// LLVOAvatar* avatar = NULL;
|
|
// if (avatar_id.asUUID().notNull())
|
|
// {
|
|
// avatar = find_avatar_from_object(avatar_id.asUUID());
|
|
// }
|
|
// else
|
|
// {
|
|
// avatar = find_avatar_from_object(
|
|
// LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
|
|
// }
|
|
//
|
|
// if( avatar )
|
|
// {
|
|
// LLSD payload;
|
|
// payload["avatar_id"] = avatar->getID();
|
|
// std::string fullname = avatar->getFullname();
|
|
//
|
|
// const LLVector3d& pos = avatar->getPositionGlobal();
|
|
// LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos)->getParcel();
|
|
//
|
|
// if (LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_MANAGE_BANNED))
|
|
// {
|
|
// payload["ban_enabled"] = true;
|
|
// if (!fullname.empty())
|
|
// {
|
|
// LLSD args;
|
|
// args["AVATAR_NAME"] = fullname;
|
|
// [RLVa:KB] - Checked: RLVa-1.0.0
|
|
// args["AVATAR_NAME"] = (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) ? fullname : RlvStrings::getAnonym(fullname);
|
|
// [/RLVa:KB]
|
|
// LLNotificationsUtil::add("EjectAvatarFullname",
|
|
// args,
|
|
// payload,
|
|
// callback_eject);
|
|
// }
|
|
// else
|
|
// {
|
|
// LLNotificationsUtil::add("EjectAvatarFullname",
|
|
// LLSD(),
|
|
// payload,
|
|
// callback_eject);
|
|
// }
|
|
// }
|
|
// else
|
|
// {
|
|
// payload["ban_enabled"] = false;
|
|
// if (!fullname.empty())
|
|
// {
|
|
// LLSD args;
|
|
// args["AVATAR_NAME"] = fullname;
|
|
// [RLVa:KB] - Checked: RLVa-1.0.0
|
|
// args["AVATAR_NAME"] = (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) ? fullname : RlvStrings::getAnonym(fullname);
|
|
// [/RLVa:KB]
|
|
// LLNotificationsUtil::add("EjectAvatarFullnameNoBan",
|
|
// args,
|
|
// payload,
|
|
// callback_eject);
|
|
// }
|
|
// else
|
|
// {
|
|
// LLNotificationsUtil::add("EjectAvatarNoBan",
|
|
// LLSD(),
|
|
// payload,
|
|
// callback_eject);
|
|
// }
|
|
// }
|
|
// }
|
|
}
|
|
|
|
bool my_profile_visible()
|
|
{
|
|
LLFloater* floaterp = LLAvatarActions::getProfileFloater(gAgentID);
|
|
return floaterp && floaterp->isInVisibleChain();
|
|
}
|
|
|
|
bool picks_tab_visible()
|
|
{
|
|
return my_profile_visible() && LLAvatarActions::isPickTabSelected(gAgentID);
|
|
}
|
|
|
|
bool enable_freeze_eject(const LLSD& avatar_id)
|
|
{
|
|
// [SL:KB] - Patch: UI-AvatarNearbyActions | Checked: 2011-05-13 (Catznip-2.6.0a) | Added: Catznip-2.6.0a
|
|
// Use avatar_id if available, otherwise default to right-click avatar
|
|
LLUUID idAgent = avatar_id.asUUID();
|
|
if (idAgent.isNull())
|
|
{
|
|
/*const*/ LLVOAvatar* pAvatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
|
|
if (pAvatar)
|
|
idAgent = pAvatar->getID();
|
|
}
|
|
return (idAgent.notNull()) ? LLAvatarActions::canLandFreezeOrEject(idAgent) : false;
|
|
// [/SL:KB]
|
|
// // Use avatar_id if available, otherwise default to right-click avatar
|
|
// LLVOAvatar* avatar = NULL;
|
|
// if (avatar_id.asUUID().notNull())
|
|
// {
|
|
// avatar = find_avatar_from_object(avatar_id.asUUID());
|
|
// }
|
|
// else
|
|
// {
|
|
// avatar = find_avatar_from_object(
|
|
// LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
|
|
// }
|
|
// if (!avatar) return false;
|
|
//
|
|
// // Gods can always freeze
|
|
// if (gAgent.isGodlike()) return true;
|
|
//
|
|
// // Estate owners / managers can freeze
|
|
// // Parcel owners can also freeze
|
|
// const LLVector3& pos = avatar->getPositionRegion();
|
|
// const LLVector3d& pos_global = avatar->getPositionGlobal();
|
|
// LLParcel* parcel = LLViewerParcelMgr::getInstance()->selectParcelAt(pos_global)->getParcel();
|
|
// LLViewerRegion* region = avatar->getRegion();
|
|
// if (!region) return false;
|
|
//
|
|
// bool new_value = region->isOwnedSelf(pos);
|
|
// if (!new_value || region->isOwnedGroup(pos))
|
|
// {
|
|
// new_value = LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_ADMIN);
|
|
// }
|
|
// return new_value;
|
|
}
|
|
|
|
// <FS:Ansariel> FIRE-13515: Re-add give calling card
|
|
class LLAvatarGiveCard : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LL_INFOS("LLAvatarGiveCard") << "handle_give_card()" << LL_ENDL;
|
|
LLViewerObject* dest = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
// [RLVa:KB] - Checked: 2010-06-04 (RLVa-1.2.0d) | Modified: RLVa-1.2.0d | OK
|
|
//if(dest && dest->isAvatar())
|
|
if ( (dest && dest->isAvatar()) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES)) )
|
|
// [/RLVa:KB]
|
|
{
|
|
bool found_name = false;
|
|
LLSD args;
|
|
LLSD old_args;
|
|
LLNameValue* nvfirst = dest->getNVPair("FirstName");
|
|
LLNameValue* nvlast = dest->getNVPair("LastName");
|
|
if(nvfirst && nvlast)
|
|
{
|
|
std::string full_name = gCacheName->buildFullName(nvfirst->getString(), nvlast->getString());
|
|
args["NAME"] = full_name;
|
|
old_args["NAME"] = full_name;
|
|
found_name = true;
|
|
}
|
|
LLViewerRegion* region = dest->getRegion();
|
|
LLHost dest_host;
|
|
if(region)
|
|
{
|
|
dest_host = region->getHost();
|
|
}
|
|
if(found_name && dest_host.isOk())
|
|
{
|
|
LLMessageSystem* msg = gMessageSystem;
|
|
msg->newMessage("OfferCallingCard");
|
|
msg->nextBlockFast(_PREHASH_AgentData);
|
|
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
|
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
|
msg->nextBlockFast(_PREHASH_AgentBlock);
|
|
msg->addUUIDFast(_PREHASH_DestID, dest->getID());
|
|
LLUUID transaction_id;
|
|
transaction_id.generate();
|
|
msg->addUUIDFast(_PREHASH_TransactionID, transaction_id);
|
|
msg->sendReliable(dest_host);
|
|
LLNotificationsUtil::add("OfferedCard", args);
|
|
}
|
|
else
|
|
{
|
|
LLNotificationsUtil::add("CantOfferCallingCard", old_args);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:Ansariel> FIRE-13515: Re-add give calling card
|
|
|
|
bool callback_leave_group(const LLSD& notification, const LLSD& response)
|
|
{
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
if (option == 0)
|
|
{
|
|
LLMessageSystem *msg = gMessageSystem;
|
|
|
|
msg->newMessageFast(_PREHASH_LeaveGroupRequest);
|
|
msg->nextBlockFast(_PREHASH_AgentData);
|
|
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
|
|
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
|
msg->nextBlockFast(_PREHASH_GroupData);
|
|
msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID() );
|
|
gAgent.sendReliableMessage();
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void append_aggregate(std::string& string, const LLAggregatePermissions& ag_perm, PermissionBit bit, const char* txt)
|
|
{
|
|
LLAggregatePermissions::EValue val = ag_perm.getValue(bit);
|
|
std::string buffer;
|
|
switch(val)
|
|
{
|
|
case LLAggregatePermissions::AP_NONE:
|
|
buffer = llformat( "* %s None\n", txt);
|
|
break;
|
|
case LLAggregatePermissions::AP_SOME:
|
|
buffer = llformat( "* %s Some\n", txt);
|
|
break;
|
|
case LLAggregatePermissions::AP_ALL:
|
|
buffer = llformat( "* %s All\n", txt);
|
|
break;
|
|
case LLAggregatePermissions::AP_EMPTY:
|
|
default:
|
|
break;
|
|
}
|
|
string.append(buffer);
|
|
}
|
|
|
|
bool enable_buy_object()
|
|
{
|
|
// In order to buy, there must only be 1 purchaseable object in
|
|
// the selection manager.
|
|
if(LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() != 1) return false;
|
|
LLViewerObject* obj = NULL;
|
|
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
|
|
if(node)
|
|
{
|
|
obj = node->getObject();
|
|
if(!obj) return false;
|
|
|
|
if( for_sale_selection(node) )
|
|
{
|
|
// [RLVa:KB] - @buy
|
|
if (!RlvActions::canBuyObject(obj->getID()))
|
|
return false;
|
|
// [/RLVa:KB]
|
|
|
|
// *NOTE: Is this needed? This checks to see if anyone owns the
|
|
// object, dating back to when we had "public" objects owned by
|
|
// no one. JC
|
|
if(obj->permAnyOwner()) return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Note: This will only work if the selected object's data has been
|
|
// received by the viewer and cached in the selection manager.
|
|
void handle_buy_object(LLSaleInfo sale_info)
|
|
{
|
|
if(!LLSelectMgr::getInstance()->selectGetAllRootsValid())
|
|
{
|
|
LLNotificationsUtil::add("UnableToBuyWhileDownloading");
|
|
return;
|
|
}
|
|
|
|
LLUUID owner_id;
|
|
std::string owner_name;
|
|
bool owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
|
|
if (!owners_identical)
|
|
{
|
|
LLNotificationsUtil::add("CannotBuyObjectsFromDifferentOwners");
|
|
return;
|
|
}
|
|
|
|
LLPermissions perm;
|
|
bool valid = LLSelectMgr::getInstance()->selectGetPermissions(perm);
|
|
LLAggregatePermissions ag_perm;
|
|
valid &= LLSelectMgr::getInstance()->selectGetAggregatePermissions(ag_perm);
|
|
if(!valid || !sale_info.isForSale() || !perm.allowTransferTo(gAgent.getID()))
|
|
{
|
|
LLNotificationsUtil::add("ObjectNotForSale");
|
|
return;
|
|
}
|
|
|
|
LLFloaterBuy::show(sale_info);
|
|
}
|
|
|
|
|
|
void handle_buy_contents(LLSaleInfo sale_info)
|
|
{
|
|
LLFloaterBuyContents::show(sale_info);
|
|
}
|
|
|
|
void handle_region_dump_temp_asset_data()
|
|
{
|
|
LL_INFOS() << "Dumping temporary asset data to simulator logs" << LL_ENDL;
|
|
std::vector<std::string> strings;
|
|
LLUUID invoice;
|
|
send_generic_message("dumptempassetdata", strings, invoice);
|
|
}
|
|
|
|
void handle_region_clear_temp_asset_data()
|
|
{
|
|
LL_INFOS() << "Clearing temporary asset data" << LL_ENDL;
|
|
std::vector<std::string> strings;
|
|
LLUUID invoice;
|
|
send_generic_message("cleartempassetdata", strings, invoice);
|
|
}
|
|
|
|
void handle_region_dump_settings()
|
|
{
|
|
LLViewerRegion* regionp = gAgent.getRegion();
|
|
if (regionp)
|
|
{
|
|
LL_INFOS() << "Damage: " << (regionp->getAllowDamage() ? "on" : "off") << LL_ENDL;
|
|
LL_INFOS() << "Landmark: " << (regionp->getAllowLandmark() ? "on" : "off") << LL_ENDL;
|
|
LL_INFOS() << "SetHome: " << (regionp->getAllowSetHome() ? "on" : "off") << LL_ENDL;
|
|
LL_INFOS() << "ResetHome: " << (regionp->getResetHomeOnTeleport() ? "on" : "off") << LL_ENDL;
|
|
LL_INFOS() << "SunFixed: " << (regionp->getSunFixed() ? "on" : "off") << LL_ENDL;
|
|
LL_INFOS() << "BlockFly: " << (regionp->getBlockFly() ? "on" : "off") << LL_ENDL;
|
|
LL_INFOS() << "AllowP2P: " << (regionp->getAllowDirectTeleport() ? "on" : "off") << LL_ENDL;
|
|
LL_INFOS() << "Water: " << (regionp->getWaterHeight()) << LL_ENDL;
|
|
}
|
|
}
|
|
|
|
void handle_dump_group_info()
|
|
{
|
|
gAgent.dumpGroupInfo();
|
|
}
|
|
|
|
void handle_dump_capabilities_info()
|
|
{
|
|
LLViewerRegion* regionp = gAgent.getRegion();
|
|
if (regionp)
|
|
{
|
|
regionp->logActiveCapabilities();
|
|
}
|
|
}
|
|
|
|
void handle_dump_region_object_cache()
|
|
{
|
|
LLViewerRegion* regionp = gAgent.getRegion();
|
|
if (regionp)
|
|
{
|
|
regionp->dumpCache();
|
|
}
|
|
}
|
|
|
|
void handle_reset_interest_lists()
|
|
{
|
|
// Check all regions and reset their interest list
|
|
for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin();
|
|
iter != LLWorld::getInstance()->getRegionList().end();
|
|
++iter)
|
|
{
|
|
LLViewerRegion *regionp = *iter;
|
|
if (regionp && regionp->isAlive() && regionp->capabilitiesReceived())
|
|
{
|
|
regionp->resetInterestList();
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void handle_dump_focus()
|
|
{
|
|
LLUICtrl *ctrl = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
|
|
|
|
LL_INFOS() << "Keyboard focus " << (ctrl ? ctrl->getName() : "(none)") << LL_ENDL;
|
|
}
|
|
|
|
class LLSelfStandUp : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gAgent.standUp();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
bool enable_standup_self()
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.2.0c) | Modified: RLVa-1.0.0g
|
|
return isAgentAvatarValid() && gAgentAvatarp->isSitting() && RlvActions::canStand();
|
|
// [/RLVa:KB]
|
|
// return isAgentAvatarValid() && gAgentAvatarp->isSitting();
|
|
}
|
|
|
|
class LLSelfSitDown : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gAgent.sitDown();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
bool show_sitdown_self()
|
|
{
|
|
return isAgentAvatarValid() && !gAgentAvatarp->isSitting();
|
|
}
|
|
|
|
bool enable_sitdown_self()
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-08-28 (RLVa-1.2.1a) | Added: RLVa-1.2.1a
|
|
return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying() && !gRlvHandler.hasBehaviour(RLV_BHVR_SIT);
|
|
// [/RLVa:KB]
|
|
// return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying();
|
|
}
|
|
|
|
class LLSelfToggleSitStand : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (isAgentAvatarValid())
|
|
{
|
|
if (gAgentAvatarp->isSitting())
|
|
{
|
|
gAgent.standUp();
|
|
}
|
|
else
|
|
{
|
|
gAgent.sitDown();
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
bool enable_sit_stand()
|
|
{
|
|
return enable_sitdown_self() || enable_standup_self();
|
|
}
|
|
|
|
bool enable_fly_land()
|
|
{
|
|
return gAgent.getFlying() || LLAgent::enableFlying();
|
|
}
|
|
|
|
// Force sit -KC
|
|
class FSSelfForceSit : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (!gAgentAvatarp->isSitting() && !gRlvHandler.hasBehaviour(RLV_BHVR_SIT))
|
|
{
|
|
gAgent.sitDown();
|
|
}
|
|
else if (gAgentAvatarp->isSitting() && !gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT))
|
|
{
|
|
gAgent.standUp();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
bool enable_forcesit_self()
|
|
{
|
|
return isAgentAvatarValid() &&
|
|
((!gAgentAvatarp->isSitting() && !gRlvHandler.hasBehaviour(RLV_BHVR_SIT)) ||
|
|
(gAgentAvatarp->isSitting() && !gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)));
|
|
}
|
|
|
|
class FSSelfCheckForceSit : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (!isAgentAvatarValid())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return gAgentAvatarp->isSitting();
|
|
}
|
|
};
|
|
|
|
// Phantom mode -KC & <FS:CR>
|
|
class FSSelfToggleMoveLock : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (LLGridManager::getInstance()->isInSecondLife())
|
|
{
|
|
make_ui_sound("UISndMovelockToggle");
|
|
bool new_value = !gSavedPerAccountSettings.getBOOL("UseMoveLock");
|
|
gSavedPerAccountSettings.setBOOL("UseMoveLock", new_value);
|
|
if (new_value)
|
|
{
|
|
LLNotificationsUtil::add("MovelockEnabling", LLSD());
|
|
}
|
|
else
|
|
{
|
|
LLNotificationsUtil::add("MovelockDisabling", LLSD());
|
|
}
|
|
}
|
|
#ifdef OPENSIM
|
|
else
|
|
{
|
|
gAgent.togglePhantom();
|
|
}
|
|
#endif // OPENSIM
|
|
//TODO: feedback to local chat
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
class FSSelfCheckMoveLock : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value(false);
|
|
if (LLGridManager::getInstance()->isInSecondLife())
|
|
{
|
|
new_value = gSavedPerAccountSettings.getBOOL("UseMoveLock");
|
|
}
|
|
#ifdef OPENSIM
|
|
else
|
|
{
|
|
new_value = gAgent.getPhantom();
|
|
}
|
|
#endif // OPENSIM
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
bool enable_bridge_function()
|
|
{
|
|
return FSLSLBridge::instance().canUseBridge();
|
|
}
|
|
|
|
bool enable_move_lock()
|
|
{
|
|
#ifdef OPENSIM
|
|
// Phantom mode always works on opensim, at least right now.
|
|
if (LLGridManager::getInstance()->isInOpenSim())
|
|
return true;
|
|
#endif // OPENSIM
|
|
return enable_bridge_function();
|
|
}
|
|
|
|
bool enable_script_info()
|
|
{
|
|
return (!LLSelectMgr::getInstance()->getSelection()->isEmpty()
|
|
&& enable_bridge_function());
|
|
}
|
|
// </FS:CR>
|
|
|
|
// [SJ - Adding IgnorePrejump in Menu ]
|
|
class FSSelfToggleIgnorePreJump : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gSavedSettings.setBOOL("FSIgnoreFinishAnimation", !gSavedSettings.getBOOL("FSIgnoreFinishAnimation"));
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// [SJ - Adding IgnorePrejump in Menu ]
|
|
class FSSelfCheckIgnorePreJump : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gSavedSettings.getBOOL("FSIgnoreFinishAnimation");
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLCheckPanelPeopleTab : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string panel_name = userdata.asString();
|
|
|
|
LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name);
|
|
if(panel && panel->isInVisibleChain())
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
// Toggle one of "People" panel tabs in side tray.
|
|
class LLTogglePanelPeopleTab : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string panel_name = userdata.asString();
|
|
|
|
LLSD param;
|
|
param["people_panel_tab_name"] = panel_name;
|
|
|
|
// <FS:Ansariel> Handle blocklist separately because of standalone option
|
|
if (panel_name == "blocked_panel")
|
|
{
|
|
if (gSavedSettings.getBOOL("FSUseStandaloneBlocklistFloater"))
|
|
{
|
|
LLFloaterReg::showInstance("fs_blocklist");
|
|
}
|
|
else
|
|
{
|
|
togglePeoplePanel(panel_name, param);
|
|
}
|
|
return true;
|
|
}
|
|
// </FS:Ansariel>
|
|
|
|
// <FS:Zi> Open groups and friends lists in communicate floater
|
|
// <FS:Lo> Adding an option to still use v2 windows
|
|
if(gSavedSettings.getBOOL("FSUseV2Friends") && gSavedSettings.getString("FSInternalSkinCurrent") != "Vintage")
|
|
{
|
|
if ( panel_name == "friends_panel"
|
|
|| panel_name == "groups_panel"
|
|
|| panel_name == "nearby_panel"
|
|
|| panel_name == "blocked_panel"
|
|
|| panel_name == "contact_sets_panel")
|
|
{
|
|
return togglePeoplePanel(panel_name, param);
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if(panel_name=="nearby_panel")
|
|
{
|
|
return togglePeoplePanel(panel_name,param);
|
|
}
|
|
else if(panel_name=="groups_panel")
|
|
{
|
|
if (gSavedSettings.getBOOL("ContactsTornOff"))
|
|
{
|
|
FSFloaterContacts* instance = FSFloaterContacts::getInstance();
|
|
std::string activetab = instance->getChild<LLTabContainer>("friends_and_groups")->getCurrentPanel()->getName();
|
|
if (instance->getVisible() && activetab == panel_name)
|
|
{
|
|
instance->closeFloater();
|
|
}
|
|
else
|
|
{
|
|
instance->openTab("groups");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FSFloaterContacts::getInstance()->openTab("groups");
|
|
}
|
|
return true;
|
|
}
|
|
else if(panel_name=="friends_panel")
|
|
{
|
|
if (gSavedSettings.getBOOL("ContactsTornOff"))
|
|
{
|
|
FSFloaterContacts* instance = FSFloaterContacts::getInstance();
|
|
std::string activetab = instance->getChild<LLTabContainer>("friends_and_groups")->getCurrentPanel()->getName();
|
|
if (instance->getVisible() && activetab == panel_name)
|
|
{
|
|
instance->closeFloater();
|
|
}
|
|
else
|
|
{
|
|
instance->openTab("friends");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FSFloaterContacts::getInstance()->openTab("friends");
|
|
}
|
|
return true;
|
|
}
|
|
else if(panel_name=="contact_sets_panel")
|
|
{
|
|
if (gSavedSettings.getBOOL("ContactsTornOff"))
|
|
{
|
|
FSFloaterContacts* instance = FSFloaterContacts::getInstance();
|
|
std::string activetab = instance->getChild<LLTabContainer>("friends_and_groups")->getCurrentPanel()->getName();
|
|
if (instance->getVisible() && activetab == panel_name)
|
|
{
|
|
instance->closeFloater();
|
|
}
|
|
else
|
|
{
|
|
instance->openTab("contact_sets");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
FSFloaterContacts::getInstance()->openTab("contact_sets");
|
|
}
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
// </FS:Lo>
|
|
// </FS:Zi>
|
|
}
|
|
|
|
static bool togglePeoplePanel(const std::string& panel_name, const LLSD& param)
|
|
{
|
|
LLPanel *panel = LLFloaterSidePanelContainer::getPanel("people", panel_name);
|
|
if(!panel)
|
|
return false;
|
|
|
|
if (panel->isInVisibleChain())
|
|
{
|
|
LLFloaterReg::hideInstance("people");
|
|
}
|
|
else
|
|
{
|
|
LLFloaterSidePanelContainer::showPanel("people", "panel_people", param) ;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
bool check_admin_override()
|
|
{
|
|
return gAgent.getAdminOverride();
|
|
}
|
|
|
|
void handle_admin_override_toggle()
|
|
{
|
|
gAgent.setAdminOverride(!gAgent.getAdminOverride());
|
|
|
|
// The above may have affected which debug menus are visible
|
|
show_debug_menus();
|
|
}
|
|
|
|
void handle_visual_leak_detector_toggle()
|
|
{
|
|
static bool vld_enabled = false;
|
|
|
|
if ( vld_enabled )
|
|
{
|
|
#ifdef INCLUDE_VLD
|
|
// only works for debug builds (hard coded into vld.h)
|
|
#if defined(_DEBUG) || defined(VLD_FORCE_ENABLE)
|
|
// start with Visual Leak Detector turned off
|
|
VLDDisable();
|
|
#endif // _DEBUG
|
|
#endif // INCLUDE_VLD
|
|
vld_enabled = false;
|
|
}
|
|
else
|
|
{
|
|
#ifdef INCLUDE_VLD
|
|
// only works for debug builds (hard coded into vld.h)
|
|
#if defined(_DEBUG) || defined(VLD_FORCE_ENABLE)
|
|
// start with Visual Leak Detector turned off
|
|
VLDEnable();
|
|
#endif // _DEBUG
|
|
#endif // INCLUDE_VLD
|
|
|
|
vld_enabled = true;
|
|
};
|
|
}
|
|
|
|
void handle_god_mode()
|
|
{
|
|
gAgent.requestEnterGodMode();
|
|
}
|
|
|
|
void handle_leave_god_mode()
|
|
{
|
|
gAgent.requestLeaveGodMode();
|
|
}
|
|
|
|
void set_god_level(U8 god_level)
|
|
{
|
|
U8 old_god_level = gAgent.getGodLevel();
|
|
gAgent.setGodLevel( god_level );
|
|
LLViewerParcelMgr::getInstance()->notifyObservers();
|
|
|
|
// God mode changes region visibility
|
|
LLWorldMap::getInstance()->reloadItems(true);
|
|
|
|
// inventory in items may change in god mode
|
|
gObjectList.dirtyAllObjectInventory();
|
|
|
|
if(gViewerWindow)
|
|
{
|
|
gViewerWindow->setMenuBackgroundColor(god_level > GOD_NOT,
|
|
!LLGridManager::getInstance()->isInSLBeta());
|
|
}
|
|
|
|
LLSD args;
|
|
if(god_level > GOD_NOT)
|
|
{
|
|
args["LEVEL"] = llformat("%d",(S32)god_level);
|
|
LLNotificationsUtil::add("EnteringGodMode", args);
|
|
}
|
|
else
|
|
{
|
|
args["LEVEL"] = llformat("%d",(S32)old_god_level);
|
|
LLNotificationsUtil::add("LeavingGodMode", args);
|
|
}
|
|
|
|
// changing god-level can affect which menus we see
|
|
show_debug_menus();
|
|
|
|
// changing god-level can invalidate search results
|
|
LLFloaterSearch *search = dynamic_cast<LLFloaterSearch*>(LLFloaterReg::getInstance("search"));
|
|
if (search)
|
|
{
|
|
search->godLevelChanged(god_level);
|
|
}
|
|
}
|
|
|
|
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
|
|
void handle_toggle_hacked_godmode()
|
|
{
|
|
gHackGodmode = !gHackGodmode;
|
|
set_god_level(gHackGodmode ? GOD_MAINTENANCE : GOD_NOT);
|
|
}
|
|
|
|
bool check_toggle_hacked_godmode()
|
|
{
|
|
return gHackGodmode;
|
|
}
|
|
|
|
bool enable_toggle_hacked_godmode()
|
|
{
|
|
return LLGridManager::getInstance()->isInSLBeta();
|
|
}
|
|
#endif
|
|
|
|
void process_grant_godlike_powers(LLMessageSystem* msg, void**)
|
|
{
|
|
LLUUID agent_id;
|
|
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
|
|
LLUUID session_id;
|
|
msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
|
|
if((agent_id == gAgent.getID()) && (session_id == gAgent.getSessionID()))
|
|
{
|
|
U8 god_level;
|
|
msg->getU8Fast(_PREHASH_GrantData, _PREHASH_GodLevel, god_level);
|
|
set_god_level(god_level);
|
|
}
|
|
else
|
|
{
|
|
LL_WARNS() << "Grant godlike for wrong agent " << agent_id << LL_ENDL;
|
|
}
|
|
}
|
|
|
|
bool is_agent_mappable(const LLUUID& agent_id)
|
|
{
|
|
const LLRelationship* buddy_info = NULL;
|
|
bool is_friend = LLAvatarActions::isFriend(agent_id);
|
|
|
|
if (is_friend)
|
|
buddy_info = LLAvatarTracker::instance().getBuddyInfo(agent_id);
|
|
|
|
return (buddy_info &&
|
|
buddy_info->isOnline() &&
|
|
buddy_info->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)
|
|
);
|
|
}
|
|
|
|
|
|
// Enable a menu item when you don't have someone's card.
|
|
class LLAvatarEnableAddFriend : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
|
|
// bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID());
|
|
// [RLVa:KB] - Checked: RLVa-1.2.0
|
|
bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID()) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID()));
|
|
// [/RLVa:KB]
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
void request_friendship(const LLUUID& dest_id)
|
|
{
|
|
LLViewerObject* dest = gObjectList.findObject(dest_id);
|
|
if(dest && dest->isAvatar())
|
|
{
|
|
std::string full_name;
|
|
LLNameValue* nvfirst = dest->getNVPair("FirstName");
|
|
LLNameValue* nvlast = dest->getNVPair("LastName");
|
|
if(nvfirst && nvlast)
|
|
{
|
|
full_name = LLCacheName::buildFullName(
|
|
nvfirst->getString(), nvlast->getString());
|
|
}
|
|
if (!full_name.empty())
|
|
{
|
|
LLAvatarActions::requestFriendshipDialog(dest_id, full_name);
|
|
}
|
|
else
|
|
{
|
|
LLNotificationsUtil::add("CantOfferFriendship");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
class LLEditEnableCustomizeAvatar : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// bool new_value = gAgentWearables.areWearablesLoaded();
|
|
// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.2.0c) | Modified: RLVa-1.0.0g
|
|
bool new_value = gAgentWearables.areWearablesLoaded() && ((!rlv_handler_t::isEnabled()) || (RlvActions::canStand()));
|
|
// [/RLVa:KB]
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLEnableEditShape : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return gAgentWearables.isWearableModifiable(LLWearableType::WT_SHAPE, 0);
|
|
}
|
|
};
|
|
|
|
class LLEnableHoverHeight : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// <FS:Ansariel> Legacy baking avatar z-offset
|
|
//return gAgent.getRegion() && gAgent.getRegion()->avatarHoverHeightEnabled();
|
|
return (gAgent.getRegion() && gAgent.getRegion()->avatarHoverHeightEnabled()) || (isAgentAvatarValid() && !gAgentAvatarp->isUsingServerBakes());
|
|
// </FS:Ansariel>
|
|
}
|
|
};
|
|
|
|
class LLEnableEditPhysics : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
//return gAgentWearables.isWearableModifiable(LLWearableType::WT_SHAPE, 0);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
bool is_object_sittable()
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-03-06 (RLVa-1.2.0c) | Added: RLVa-1.1.0j
|
|
// RELEASE-RLVa: [SL-2.2.0] Make sure we're examining the same object that handle_sit_or_stand() will request a sit for
|
|
if (rlv_handler_t::isEnabled())
|
|
{
|
|
const LLPickInfo& pick = LLToolPie::getInstance()->getPick();
|
|
if ( (pick.mObjectID.notNull()) && (!RlvActions::canSit(pick.getObject(), pick.mObjectOffset)) )
|
|
return false;
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
|
|
if (object && object->getPCode() == LL_PCODE_VOLUME)
|
|
{
|
|
return true;
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
// only works on pie menu
|
|
void handle_object_sit(LLViewerObject* object, const LLVector3& offset)
|
|
{
|
|
// get object selection offset
|
|
|
|
// if (object && object->getPCode() == LL_PCODE_VOLUME)
|
|
// [RLVa:KB] - Checked: 2010-03-06 (RLVa-1.2.0c) | Modified: RLVa-1.2.0c
|
|
if ( (object && object->getPCode() == LL_PCODE_VOLUME) &&
|
|
((!rlv_handler_t::isEnabled()) || (RlvActions::canSit(object, offset))) )
|
|
// [/RLVa:KB]
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-08-29 (RLVa-1.2.1c) | Added: RLVa-1.2.1c
|
|
if ( (gRlvHandler.hasBehaviour(RLV_BHVR_STANDTP)) && (isAgentAvatarValid()) )
|
|
{
|
|
if (gAgentAvatarp->isSitting())
|
|
{
|
|
gAgent.standUp();
|
|
return;
|
|
}
|
|
gRlvHandler.setSitSource(gAgent.getPositionGlobal());
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit);
|
|
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
|
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
|
gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
|
gMessageSystem->nextBlockFast(_PREHASH_TargetObject);
|
|
gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID);
|
|
gMessageSystem->addVector3Fast(_PREHASH_Offset, offset);
|
|
|
|
object->getRegion()->sendReliableMessage();
|
|
}
|
|
}
|
|
|
|
void handle_object_sit_or_stand()
|
|
{
|
|
LLPickInfo pick = LLToolPie::getInstance()->getPick();
|
|
LLViewerObject *object = pick.getObject();
|
|
if (!object || pick.mPickType == LLPickInfo::PICK_FLORA)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (sitting_on_selection())
|
|
{
|
|
gAgent.standUp();
|
|
return;
|
|
}
|
|
|
|
handle_object_sit(object, pick.mObjectOffset);
|
|
}
|
|
|
|
void handle_object_sit(const LLUUID& object_id)
|
|
{
|
|
LLViewerObject* obj = gObjectList.findObject(object_id);
|
|
if (!obj)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LLVector3 offset(0, 0, 0);
|
|
handle_object_sit(obj, offset);
|
|
}
|
|
|
|
void near_sit_down_point(bool success, void*)
|
|
{
|
|
if (success)
|
|
{
|
|
gAgent.setFlying(false);
|
|
gAgent.clearControlFlags(AGENT_CONTROL_STAND_UP); // might have been set by autopilot
|
|
gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
|
|
}
|
|
}
|
|
|
|
class LLLandSit : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f
|
|
if ( (rlv_handler_t::isEnabled()) && ((!RlvActions::canStand()) || (gRlvHandler.hasBehaviour(RLV_BHVR_SIT))) )
|
|
return true;
|
|
// [/RLVa:KB]
|
|
|
|
if (gAgent.isSitting())
|
|
{
|
|
gAgent.standUp();
|
|
}
|
|
LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;
|
|
|
|
LLQuaternion target_rot;
|
|
if (isAgentAvatarValid())
|
|
{
|
|
target_rot = gAgentAvatarp->getRotation();
|
|
}
|
|
else
|
|
{
|
|
target_rot = gAgent.getFrameAgent().getQuaternion();
|
|
}
|
|
gAgent.startAutoPilotGlobal(posGlobal, "Sit", &target_rot, near_sit_down_point, NULL, 0.7f);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLLandCanSit : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVector3d posGlobal = LLToolPie::getInstance()->getPick().mPosGlobal;
|
|
return !posGlobal.isExactlyZero(); // valid position, not beyond draw distance
|
|
}
|
|
};
|
|
|
|
//-------------------------------------------------------------------
|
|
// Help menu functions
|
|
//-------------------------------------------------------------------
|
|
|
|
//
|
|
// Major mode switching
|
|
//
|
|
void reset_view_final(bool proceed);
|
|
|
|
void handle_reset_view()
|
|
{
|
|
if (gAgentCamera.cameraCustomizeAvatar())
|
|
{
|
|
// switching to outfit selector should automagically save any currently edited wearable
|
|
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits"));
|
|
}
|
|
|
|
// <FS:Zi> Added optional V1 behavior so the avatar turns into camera direction after hitting ESC
|
|
// gAgentCamera.setFocusOnAvatar(true, false, false);
|
|
if (!gSavedSettings.getBOOL("ResetViewTurnsAvatar"))
|
|
{
|
|
// The only thing we actually want to do here is set LLAgent::mFocusOnAvatar to true,
|
|
// since this prevents the avatar from turning.
|
|
gAgentCamera.setFocusOnAvatar(true, false, false);
|
|
}
|
|
// </FS:Zi>
|
|
|
|
reset_view_final(true);
|
|
LLFloaterCamera::resetCameraMode();
|
|
}
|
|
|
|
// <FS:Zi> Add reset camera angles menu
|
|
void handle_reset_camera_angles()
|
|
{
|
|
handle_reset_view();
|
|
|
|
// Camera focus and offset with CTRL/SHIFT + Scroll wheel
|
|
gSavedSettings.getControl("FocusOffsetRearView")->resetToDefault();
|
|
gSavedSettings.getControl("CameraOffsetRearView")->resetToDefault();
|
|
|
|
// warn the user if there is a scripted followcam active that might stop a camera reset
|
|
PermissionsTracker::instance().warnFollowcam();
|
|
}
|
|
// </FS:Zi>
|
|
|
|
class LLViewResetView : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_reset_view();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// <FS:Zi> Add reset camera angles menu
|
|
class LLViewResetCameraAngles : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
handle_reset_camera_angles();
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:Zi>
|
|
|
|
// Note: extra parameters allow this function to be called from dialog.
|
|
void reset_view_final(bool proceed)
|
|
{
|
|
if( !proceed )
|
|
{
|
|
return;
|
|
}
|
|
|
|
gAgentCamera.resetView(true, true);
|
|
gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
|
|
}
|
|
|
|
class LLViewLookAtLastChatter : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gAgentCamera.lookAtLastChat();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLViewMouselook : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (!gAgentCamera.cameraMouselook())
|
|
{
|
|
gAgentCamera.changeCameraToMouselook();
|
|
}
|
|
else
|
|
{
|
|
// NaCl - Rightclick-mousewheel zoom
|
|
LLVector3 _NACL_MLFovValues = gSavedSettings.getVector3("_NACL_MLFovValues");
|
|
F32 CameraAngle = gSavedSettings.getF32("CameraAngle");
|
|
if (_NACL_MLFovValues.mV[VZ] > 0.0f)
|
|
{
|
|
_NACL_MLFovValues.mV[VY] = CameraAngle;
|
|
_NACL_MLFovValues.mV[VZ] = 0.0f;
|
|
gSavedSettings.setVector3("_NACL_MLFovValues", _NACL_MLFovValues);
|
|
gSavedSettings.setF32("CameraAngle", _NACL_MLFovValues.mV[VX]);
|
|
}
|
|
// NaCl End
|
|
gAgentCamera.changeCameraToDefault();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLViewDefaultUISize : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gSavedSettings.setF32("UIScaleFactor", 1.0f);
|
|
gSavedSettings.setBOOL("UIAutoScale", false);
|
|
gViewerWindow->reshape(gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw());
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLViewToggleUI : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if(gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
|
|
{
|
|
LLNotification::Params params("ConfirmHideUI");
|
|
params.functor.function(boost::bind(&LLViewToggleUI::confirm, this, _1, _2));
|
|
LLSD substitutions;
|
|
// <FS:Ansariel> Notification not showing if hiding the UI
|
|
//#if LL_DARWIN
|
|
// substitutions["SHORTCUT"] = "Cmd+Shift+U";
|
|
//#else
|
|
// substitutions["SHORTCUT"] = "Ctrl+Shift+U";
|
|
//#endif
|
|
substitutions["SHORTCUT"] = "Alt+Shift+U";
|
|
// </FS:Ansariel>
|
|
params.substitutions = substitutions;
|
|
if (!gSavedSettings.getBOOL("HideUIControls"))
|
|
{
|
|
// hiding, so show notification
|
|
LLNotifications::instance().add(params);
|
|
}
|
|
else
|
|
{
|
|
LLNotifications::instance().forceResponse(params, 0);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void confirm(const LLSD& notification, const LLSD& response)
|
|
{
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
|
|
if (option == 0) // OK
|
|
{
|
|
gViewerWindow->setUIVisibility(gSavedSettings.getBOOL("HideUIControls"));
|
|
LLPanelStandStopFlying::getInstance()->setVisible(gSavedSettings.getBOOL("HideUIControls"));
|
|
gSavedSettings.setBOOL("HideUIControls",!gSavedSettings.getBOOL("HideUIControls"));
|
|
}
|
|
}
|
|
};
|
|
|
|
// <FS:Ansariel> Notification not showing if hiding the UI
|
|
class LLViewCheckToggleUI : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return gViewerWindow->getUIVisibility();
|
|
}
|
|
};
|
|
// </FS:Ansariel>
|
|
|
|
void handle_object_owner_permissive()
|
|
{
|
|
// only send this if they're a god.
|
|
if(gAgent.isGodlike())
|
|
{
|
|
// do the objects.
|
|
LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_BASE, true, PERM_ALL, true);
|
|
LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, true, PERM_ALL, true);
|
|
}
|
|
}
|
|
|
|
void handle_object_owner_self()
|
|
{
|
|
// only send this if they're a god.
|
|
if(gAgent.isGodlike())
|
|
{
|
|
LLSelectMgr::getInstance()->sendOwner(gAgent.getID(), gAgent.getGroupID(), true);
|
|
}
|
|
}
|
|
|
|
// Shortcut to set owner permissions to not editable.
|
|
void handle_object_lock()
|
|
{
|
|
LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_OWNER, false, PERM_MODIFY);
|
|
}
|
|
|
|
void handle_object_asset_ids()
|
|
{
|
|
// only send this if they're a god.
|
|
if (gAgent.isGodlike())
|
|
{
|
|
LLSelectMgr::getInstance()->sendGodlikeRequest("objectinfo", "assetids");
|
|
}
|
|
}
|
|
|
|
void handle_force_parcel_owner_to_me()
|
|
{
|
|
LLViewerParcelMgr::getInstance()->sendParcelGodForceOwner( gAgent.getID() );
|
|
}
|
|
|
|
void handle_force_parcel_to_content()
|
|
{
|
|
LLViewerParcelMgr::getInstance()->sendParcelGodForceToContent();
|
|
}
|
|
|
|
void handle_claim_public_land()
|
|
{
|
|
if (LLViewerParcelMgr::getInstance()->getSelectionRegion() != gAgent.getRegion())
|
|
{
|
|
LLNotificationsUtil::add("ClaimPublicLand");
|
|
return;
|
|
}
|
|
|
|
LLVector3d west_south_global;
|
|
LLVector3d east_north_global;
|
|
LLViewerParcelMgr::getInstance()->getSelection(west_south_global, east_north_global);
|
|
LLVector3 west_south = gAgent.getPosAgentFromGlobal(west_south_global);
|
|
LLVector3 east_north = gAgent.getPosAgentFromGlobal(east_north_global);
|
|
|
|
LLMessageSystem* msg = gMessageSystem;
|
|
msg->newMessage("GodlikeMessage");
|
|
msg->nextBlock("AgentData");
|
|
msg->addUUID("AgentID", gAgent.getID());
|
|
msg->addUUID("SessionID", gAgent.getSessionID());
|
|
msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
|
|
msg->nextBlock("MethodData");
|
|
msg->addString("Method", "claimpublicland");
|
|
msg->addUUID("Invoice", LLUUID::null);
|
|
std::string buffer;
|
|
buffer = llformat( "%f", west_south.mV[VX]);
|
|
msg->nextBlock("ParamList");
|
|
msg->addString("Parameter", buffer);
|
|
buffer = llformat( "%f", west_south.mV[VY]);
|
|
msg->nextBlock("ParamList");
|
|
msg->addString("Parameter", buffer);
|
|
buffer = llformat( "%f", east_north.mV[VX]);
|
|
msg->nextBlock("ParamList");
|
|
msg->addString("Parameter", buffer);
|
|
buffer = llformat( "%f", east_north.mV[VY]);
|
|
msg->nextBlock("ParamList");
|
|
msg->addString("Parameter", buffer);
|
|
gAgent.sendReliableMessage();
|
|
}
|
|
|
|
|
|
|
|
// HACK for easily testing new avatar geometry
|
|
void handle_god_request_avatar_geometry()
|
|
{
|
|
if (gAgent.isGodlike())
|
|
{
|
|
LLSelectMgr::getInstance()->sendGodlikeRequest("avatar toggle", "");
|
|
}
|
|
}
|
|
|
|
static bool get_derezzable_objects(
|
|
EDeRezDestination dest,
|
|
std::string& error,
|
|
LLViewerRegion*& first_region,
|
|
std::vector<LLViewerObjectPtr>* derez_objectsp,
|
|
bool only_check = false)
|
|
{
|
|
bool found = false;
|
|
|
|
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
|
|
|
|
if (derez_objectsp)
|
|
derez_objectsp->reserve(selection->getRootObjectCount());
|
|
|
|
// Check conditions that we can't deal with, building a list of
|
|
// everything that we'll actually be derezzing.
|
|
for (LLObjectSelection::valid_root_iterator iter = selection->valid_root_begin();
|
|
iter != selection->valid_root_end(); iter++)
|
|
{
|
|
LLSelectNode* node = *iter;
|
|
LLViewerObject* object = node->getObject();
|
|
LLViewerRegion* region = object->getRegion();
|
|
if (!first_region)
|
|
{
|
|
first_region = region;
|
|
}
|
|
else
|
|
{
|
|
if(region != first_region)
|
|
{
|
|
// Derez doesn't work at all if the some of the objects
|
|
// are in regions besides the first object selected.
|
|
|
|
// ...crosses region boundaries
|
|
error = "AcquireErrorObjectSpan";
|
|
break;
|
|
}
|
|
}
|
|
if (object->isAvatar())
|
|
{
|
|
// ...don't acquire avatars
|
|
continue;
|
|
}
|
|
|
|
// If AssetContainers are being sent back, they will appear as
|
|
// boxes in the owner's inventory.
|
|
if (object->getNVPair("AssetContainer")
|
|
&& dest != DRD_RETURN_TO_OWNER)
|
|
{
|
|
// this object is an asset container, derez its contents, not it
|
|
LL_WARNS() << "Attempt to derez deprecated AssetContainer object type not supported." << LL_ENDL;
|
|
/*
|
|
object->requestInventory(container_inventory_arrived,
|
|
(void *)(DRD_TAKE_INTO_AGENT_INVENTORY == dest));
|
|
*/
|
|
continue;
|
|
}
|
|
bool can_derez_current = false;
|
|
switch(dest)
|
|
{
|
|
case DRD_TAKE_INTO_AGENT_INVENTORY:
|
|
case DRD_TRASH:
|
|
if (!object->isPermanentEnforced() &&
|
|
((node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify())
|
|
|| (node->allowOperationOnNode(PERM_OWNER, GP_OBJECT_MANIPULATE))))
|
|
{
|
|
can_derez_current = true;
|
|
}
|
|
break;
|
|
|
|
case DRD_RETURN_TO_OWNER:
|
|
if(!object->isAttachment())
|
|
{
|
|
can_derez_current = true;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
if((node->mPermissions->allowTransferTo(gAgent.getID())
|
|
&& object->permCopy())
|
|
|| gAgent.isGodlike())
|
|
{
|
|
can_derez_current = true;
|
|
}
|
|
break;
|
|
}
|
|
if(can_derez_current)
|
|
{
|
|
found = true;
|
|
|
|
if (only_check)
|
|
// one found, no need to traverse to the end
|
|
break;
|
|
|
|
if (derez_objectsp)
|
|
derez_objectsp->push_back(object);
|
|
|
|
}
|
|
}
|
|
|
|
return found;
|
|
}
|
|
|
|
static bool can_derez(EDeRezDestination dest)
|
|
{
|
|
LLViewerRegion* first_region = NULL;
|
|
std::string error;
|
|
return get_derezzable_objects(dest, error, first_region, NULL, true);
|
|
}
|
|
|
|
static void derez_objects(
|
|
EDeRezDestination dest,
|
|
const LLUUID& dest_id,
|
|
LLViewerRegion*& first_region,
|
|
std::string& error,
|
|
std::vector<LLViewerObjectPtr>* objectsp)
|
|
{
|
|
std::vector<LLViewerObjectPtr> derez_objects;
|
|
|
|
if (!objectsp) // if objects to derez not specified
|
|
{
|
|
// get them from selection
|
|
if (!get_derezzable_objects(dest, error, first_region, &derez_objects, false))
|
|
{
|
|
LL_WARNS() << "No objects to derez" << LL_ENDL;
|
|
return;
|
|
}
|
|
|
|
objectsp = &derez_objects;
|
|
}
|
|
|
|
|
|
if(gAgentCamera.cameraMouselook())
|
|
{
|
|
gAgentCamera.changeCameraToDefault();
|
|
}
|
|
|
|
// This constant is based on (1200 - HEADER_SIZE) / 4 bytes per
|
|
// root. I lopped off a few (33) to provide a bit
|
|
// pad. HEADER_SIZE is currently 67 bytes, most of which is UUIDs.
|
|
// This gives us a maximum of 63500 root objects - which should
|
|
// satisfy anybody.
|
|
const S32 MAX_ROOTS_PER_PACKET = 250;
|
|
const S32 MAX_PACKET_COUNT = 254;
|
|
F32 packets = ceil((F32)objectsp->size() / (F32)MAX_ROOTS_PER_PACKET);
|
|
if(packets > (F32)MAX_PACKET_COUNT)
|
|
{
|
|
error = "AcquireErrorTooManyObjects";
|
|
}
|
|
|
|
if(error.empty() && objectsp->size() > 0)
|
|
{
|
|
U8 d = (U8)dest;
|
|
LLUUID tid;
|
|
tid.generate();
|
|
U8 packet_count = (U8)packets;
|
|
S32 object_index = 0;
|
|
S32 objects_in_packet = 0;
|
|
LLMessageSystem* msg = gMessageSystem;
|
|
for(U8 packet_number = 0;
|
|
packet_number < packet_count;
|
|
++packet_number)
|
|
{
|
|
msg->newMessageFast(_PREHASH_DeRezObject);
|
|
msg->nextBlockFast(_PREHASH_AgentData);
|
|
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
|
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
|
|
msg->nextBlockFast(_PREHASH_AgentBlock);
|
|
msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
|
|
msg->addU8Fast(_PREHASH_Destination, d);
|
|
msg->addUUIDFast(_PREHASH_DestinationID, dest_id);
|
|
msg->addUUIDFast(_PREHASH_TransactionID, tid);
|
|
msg->addU8Fast(_PREHASH_PacketCount, packet_count);
|
|
msg->addU8Fast(_PREHASH_PacketNumber, packet_number);
|
|
objects_in_packet = 0;
|
|
while((object_index < objectsp->size())
|
|
&& (objects_in_packet++ < MAX_ROOTS_PER_PACKET))
|
|
|
|
{
|
|
LLViewerObject* object = objectsp->at(object_index++);
|
|
msg->nextBlockFast(_PREHASH_ObjectData);
|
|
msg->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
|
|
// VEFFECT: DerezObject
|
|
LLHUDEffectSpiral* effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, true);
|
|
effectp->setPositionGlobal(object->getPositionGlobal());
|
|
effectp->setColor(LLColor4U(gAgent.getEffectColor()));
|
|
}
|
|
msg->sendReliable(first_region->getHost());
|
|
}
|
|
make_ui_sound("UISndObjectRezOut");
|
|
|
|
// Busy count decremented by inventory update, so only increment
|
|
// if will be causing an update.
|
|
if (dest != DRD_RETURN_TO_OWNER)
|
|
{
|
|
gViewerWindow->getWindow()->incBusyCount();
|
|
}
|
|
}
|
|
else if(!error.empty())
|
|
{
|
|
LLNotificationsUtil::add(error);
|
|
}
|
|
}
|
|
|
|
static void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
|
|
{
|
|
LLViewerRegion* first_region = NULL;
|
|
std::string error;
|
|
derez_objects(dest, dest_id, first_region, error, NULL);
|
|
}
|
|
|
|
static void derez_objects_separate(EDeRezDestination dest, const LLUUID &dest_id)
|
|
{
|
|
std::vector<LLViewerObjectPtr> derez_object_list;
|
|
std::string error;
|
|
LLViewerRegion* first_region = NULL;
|
|
if (!get_derezzable_objects(dest, error, first_region, &derez_object_list, false))
|
|
{
|
|
LL_WARNS() << "No objects to derez" << LL_ENDL;
|
|
return;
|
|
}
|
|
for (LLViewerObject *opjectp : derez_object_list)
|
|
{
|
|
std::vector<LLViewerObjectPtr> buf_list;
|
|
buf_list.push_back(opjectp);
|
|
derez_objects(dest, dest_id, first_region, error, &buf_list);
|
|
}
|
|
}
|
|
|
|
void handle_take_copy()
|
|
{
|
|
if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return;
|
|
|
|
// [RLVa:KB] - Checked: 2010-03-07 (RLVa-1.2.0c) | Modified: RLVa-1.2.0a
|
|
if ( (rlv_handler_t::isEnabled()) && (!RlvActions::canStand()) )
|
|
{
|
|
// Allow only if the avie isn't sitting on any of the selected objects
|
|
LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection();
|
|
RlvSelectIsSittingOn f(gAgentAvatarp);
|
|
if ( (hSel.notNull()) && (hSel->getFirstRootNode(&f, true) != NULL) )
|
|
return;
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
|
|
derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id);
|
|
}
|
|
|
|
void handle_take_separate_copy()
|
|
{
|
|
if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
|
|
return;
|
|
|
|
const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
|
|
derez_objects_separate(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id);
|
|
}
|
|
|
|
void handle_link_objects()
|
|
{
|
|
// <FS:Ansariel> We don't use a shortcut for two completely different functions based on context
|
|
//if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
|
|
//{
|
|
// LLFloaterReg::toggleInstanceOrBringToFront("places");
|
|
//}
|
|
//else
|
|
// </FS:Ansariel>
|
|
{
|
|
LLSelectMgr::getInstance()->linkObjects();
|
|
}
|
|
}
|
|
|
|
// You can return an object to its owner if it is on your land.
|
|
class LLObjectReturn : public view_listener_t
|
|
{
|
|
public:
|
|
LLObjectReturn() : mFirstRegion() {}
|
|
|
|
private:
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return true;
|
|
// [RLVa:KB] - Checked: 2010-03-24 (RLVa-1.4.0a) | Modified: RLVa-1.0.0b
|
|
if ( (rlv_handler_t::isEnabled()) && (!rlvCanDeleteOrReturn()) ) return true;
|
|
// [/RLVa:KB]
|
|
|
|
mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
|
|
|
|
// Save selected objects, so that we still know what to return after the confirmation dialog resets selection.
|
|
get_derezzable_objects(DRD_RETURN_TO_OWNER, mError, mFirstRegion, &mReturnableObjects);
|
|
|
|
LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&LLObjectReturn::onReturnToOwner, this, _1, _2));
|
|
return true;
|
|
}
|
|
|
|
bool onReturnToOwner(const LLSD& notification, const LLSD& response)
|
|
{
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
if (0 == option)
|
|
{
|
|
// Ignore category ID for this derez destination.
|
|
derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, mFirstRegion, mError, &mReturnableObjects);
|
|
}
|
|
|
|
mReturnableObjects.clear();
|
|
mError.clear();
|
|
mFirstRegion = NULL;
|
|
|
|
// drop reference to current selection
|
|
mObjectSelection = NULL;
|
|
return false;
|
|
}
|
|
|
|
LLObjectSelectionHandle mObjectSelection;
|
|
|
|
std::vector<LLViewerObjectPtr> mReturnableObjects;
|
|
std::string mError;
|
|
LLViewerRegion* mFirstRegion;
|
|
};
|
|
|
|
|
|
// Allow return to owner if one or more of the selected items is
|
|
// over land you own.
|
|
class LLObjectEnableReturn : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
|
|
{
|
|
// Do not enable if nothing selected
|
|
return false;
|
|
}
|
|
// [RLVa:KB] - Checked: 2011-05-28 (RLVa-1.4.0a) | Modified: RLVa-1.4.0a
|
|
if ( (rlv_handler_t::isEnabled()) && (!rlvCanDeleteOrReturn()) )
|
|
{
|
|
return false;
|
|
}
|
|
// [/RLVa:KB]
|
|
#ifdef HACKED_GODLIKE_VIEWER
|
|
bool new_value = true;
|
|
#else
|
|
bool new_value = false;
|
|
if (gAgent.isGodlike())
|
|
{
|
|
new_value = true;
|
|
}
|
|
else
|
|
{
|
|
new_value = can_derez(DRD_RETURN_TO_OWNER);
|
|
}
|
|
#endif
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
void force_take_copy()
|
|
{
|
|
if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return;
|
|
const LLUUID category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
|
|
derez_objects(DRD_FORCE_TO_GOD_INVENTORY, category_id);
|
|
}
|
|
|
|
void handle_take(bool take_separate)
|
|
{
|
|
// we want to use the folder this was derezzed from if it's
|
|
// available. Otherwise, derez to the normal place.
|
|
// if(LLSelectMgr::getInstance()->getSelection()->isEmpty())
|
|
// [RLVa:KB] - Checked: 2010-03-24 (RLVa-1.2.0e) | Modified: RLVa-1.0.0b
|
|
if ( (LLSelectMgr::getInstance()->getSelection()->isEmpty()) || ((rlv_handler_t::isEnabled()) && (!rlvCanDeleteOrReturn())) )
|
|
// [/RLVa:KB]
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool you_own_everything = true;
|
|
bool locked_but_takeable_object = false;
|
|
LLUUID category_id;
|
|
|
|
for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
|
|
iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
|
|
{
|
|
LLSelectNode* node = *iter;
|
|
LLViewerObject* object = node->getObject();
|
|
if(object)
|
|
{
|
|
if(!object->permYouOwner())
|
|
{
|
|
you_own_everything = false;
|
|
}
|
|
|
|
if(!object->permMove())
|
|
{
|
|
locked_but_takeable_object = true;
|
|
}
|
|
}
|
|
if(node->mFolderID.notNull())
|
|
{
|
|
if(category_id.isNull())
|
|
{
|
|
category_id = node->mFolderID;
|
|
LL_DEBUGS("HandleTake") << "Node destination folder ID = " << category_id.asString() << LL_ENDL;
|
|
}
|
|
else if(category_id != node->mFolderID)
|
|
{
|
|
// we have found two potential destinations. break out
|
|
// now and send to the default location.
|
|
category_id.setNull();
|
|
LL_DEBUGS("HandleTake") << "Conflicting node destination folders - setting to null UUID" << LL_ENDL;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
if(category_id.notNull())
|
|
{
|
|
LL_DEBUGS("HandleTake") << "Selected destination folder ID: " << category_id.asString() << " - checking if category exists in inventory model" << LL_ENDL;
|
|
|
|
// there is an unambiguous destination. See if this agent has
|
|
// such a location and it is not in the trash or library
|
|
if(!gInventory.getCategory(category_id))
|
|
{
|
|
// nope, set to NULL.
|
|
category_id.setNull();
|
|
LL_DEBUGS("HandleTake") << "Destination folder not found in inventory model - setting to null UUID" << LL_ENDL;
|
|
}
|
|
if(category_id.notNull())
|
|
{
|
|
// check trash
|
|
const LLUUID trash = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
|
|
if(category_id == trash || gInventory.isObjectDescendentOf(category_id, trash))
|
|
{
|
|
category_id.setNull();
|
|
LL_DEBUGS("HandleTake") << "Destination folder is descendent of trash folder - setting to null UUID" << LL_ENDL;
|
|
}
|
|
|
|
// check library
|
|
if(gInventory.isObjectDescendentOf(category_id, gInventory.getLibraryRootFolderID()))
|
|
{
|
|
category_id.setNull();
|
|
LL_DEBUGS("HandleTake") << "Destination folder is descendent of library folder - setting to null UUID" << LL_ENDL;
|
|
}
|
|
|
|
// check inbox
|
|
// <FS:Ansariel> Undo the SL-1579 fail
|
|
//const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
|
|
//if (category_id == inbox_id || gInventory.isObjectDescendentOf(category_id, inbox_id))
|
|
//{
|
|
// category_id.setNull();
|
|
//}
|
|
// </FS:Ansariel>
|
|
}
|
|
}
|
|
if(category_id.isNull())
|
|
{
|
|
category_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OBJECT);
|
|
LL_DEBUGS("HandleTake") << "Destination folder = null UUID - determined default category: " << category_id.asString() << LL_ENDL;
|
|
}
|
|
LLSD payload;
|
|
payload["folder_id"] = category_id;
|
|
LL_DEBUGS("HandleTake") << "Final destination folder UUID being sent to sim: " << category_id.asString() << LL_ENDL;
|
|
|
|
LLNotification::Params params("ConfirmObjectTakeLock");
|
|
params.payload(payload);
|
|
// MAINT-290
|
|
// Reason: Showing the confirmation dialog resets object selection, thus there is nothing to derez.
|
|
// Fix: pass selection to the confirm_take, so that selection doesn't "die" after confirmation dialog is opened
|
|
LLObjectSelectionHandle obj_selection = LLSelectMgr::instance().getSelection();
|
|
params.functor.function([take_separate, obj_selection](const LLSD ¬ification, const LLSD &response)
|
|
{
|
|
if (take_separate)
|
|
{
|
|
confirm_take_separate(notification, response, obj_selection);
|
|
}
|
|
else
|
|
{
|
|
confirm_take(notification, response, obj_selection);
|
|
}
|
|
});
|
|
|
|
if (locked_but_takeable_object ||
|
|
!you_own_everything)
|
|
{
|
|
if(locked_but_takeable_object && you_own_everything)
|
|
{
|
|
params.name("ConfirmObjectTakeLock");
|
|
}
|
|
else if(!locked_but_takeable_object && !you_own_everything)
|
|
{
|
|
params.name("ConfirmObjectTakeNoOwn");
|
|
}
|
|
else
|
|
{
|
|
params.name("ConfirmObjectTakeLockNoOwn");
|
|
}
|
|
|
|
LLNotifications::instance().add(params);
|
|
}
|
|
else
|
|
{
|
|
LLNotifications::instance().forceResponse(params, 0);
|
|
}
|
|
}
|
|
|
|
void handle_object_show_inspector()
|
|
{
|
|
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
|
|
LLViewerObject* objectp = selection->getFirstRootObject(true);
|
|
if (!objectp)
|
|
{
|
|
return;
|
|
}
|
|
|
|
LLSD params;
|
|
params["object_id"] = objectp->getID();
|
|
LLFloaterReg::showInstance("inspect_object", params);
|
|
}
|
|
|
|
void handle_avatar_show_inspector()
|
|
{
|
|
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
|
if(avatar)
|
|
{
|
|
LLSD params;
|
|
params["avatar_id"] = avatar->getID();
|
|
LLFloaterReg::showInstance("inspect_avatar", params);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
bool confirm_take(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection_handle)
|
|
{
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
if(enable_take() && (option == 0))
|
|
{
|
|
derez_objects(DRD_TAKE_INTO_AGENT_INVENTORY, notification["payload"]["folder_id"].asUUID());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool confirm_take_separate(const LLSD ¬ification, const LLSD &response, LLObjectSelectionHandle selection_handle)
|
|
{
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
if (enable_take() && (option == 0))
|
|
{
|
|
derez_objects_separate(DRD_TAKE_INTO_AGENT_INVENTORY, notification["payload"]["folder_id"].asUUID());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// You can take an item when it is public and transferrable, or when
|
|
// you own it. We err on the side of enabling the item when at least
|
|
// one item selected can be copied to inventory.
|
|
bool enable_take()
|
|
{
|
|
// if (sitting_on_selection())
|
|
// [RLVa:KB] - Checked: 2010-03-24 (RLVa-1.2.0e) | Modified: RLVa-1.0.0b
|
|
if ( (sitting_on_selection()) || ((rlv_handler_t::isEnabled()) && (!rlvCanDeleteOrReturn())) )
|
|
// [/RLVa:KB]
|
|
{
|
|
return false;
|
|
}
|
|
|
|
for (LLObjectSelection::valid_root_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_root_begin();
|
|
iter != LLSelectMgr::getInstance()->getSelection()->valid_root_end(); iter++)
|
|
{
|
|
LLSelectNode* node = *iter;
|
|
LLViewerObject* object = node->getObject();
|
|
if (object->isAvatar())
|
|
{
|
|
// ...don't acquire avatars
|
|
continue;
|
|
}
|
|
|
|
#ifdef HACKED_GODLIKE_VIEWER
|
|
return true;
|
|
#else
|
|
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
|
|
if (LLGridManager::getInstance()->isInSLBeta()
|
|
&& gAgent.isGodlike())
|
|
{
|
|
return true;
|
|
}
|
|
# endif
|
|
if(!object->isPermanentEnforced() &&
|
|
((node->mPermissions->allowTransferTo(gAgent.getID())
|
|
&& object->permModify())
|
|
|| (node->mPermissions->getOwner() == gAgent.getID())))
|
|
{
|
|
return !object->isAttachment();
|
|
}
|
|
#endif
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
void handle_buy_or_take()
|
|
{
|
|
if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (is_selection_buy_not_take())
|
|
{
|
|
S32 total_price = selection_price();
|
|
|
|
if (total_price <= gStatusBar->getBalance() || total_price == 0)
|
|
{
|
|
handle_buy();
|
|
}
|
|
else
|
|
{
|
|
LLStringUtil::format_map_t args;
|
|
args["AMOUNT"] = llformat("%d", total_price);
|
|
LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "this_object_costs", args ), total_price );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
handle_take();
|
|
}
|
|
}
|
|
|
|
bool visible_buy_object()
|
|
{
|
|
return is_selection_buy_not_take() && enable_buy_object();
|
|
}
|
|
|
|
bool visible_take_object()
|
|
{
|
|
return !is_selection_buy_not_take() && enable_take();
|
|
}
|
|
|
|
bool is_multiple_selection()
|
|
{
|
|
return (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 1);
|
|
}
|
|
|
|
bool is_single_selection()
|
|
{
|
|
return !is_multiple_selection();
|
|
}
|
|
|
|
bool enable_take_objects()
|
|
{
|
|
return visible_take_object() && is_multiple_selection();
|
|
}
|
|
|
|
bool tools_visible_buy_object()
|
|
{
|
|
return is_selection_buy_not_take();
|
|
}
|
|
|
|
bool tools_visible_take_object()
|
|
{
|
|
return !is_selection_buy_not_take();
|
|
}
|
|
|
|
class LLToolsEnableBuyOrTake : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool is_buy = is_selection_buy_not_take();
|
|
bool new_value = is_buy ? enable_buy_object() : enable_take();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
// This is a small helper function to determine if we have a buy or a
|
|
// take in the selection. This method is to help with the aliasing
|
|
// problems of putting buy and take in the same pie menu space. After
|
|
// a fair amont of discussion, it was determined to prefer buy over
|
|
// take. The reasoning follows from the fact that when users walk up
|
|
// to buy something, they will click on one or more items. Thus, if
|
|
// anything is for sale, it becomes a buy operation, and the server
|
|
// will group all of the buy items, and copyable/modifiable items into
|
|
// one package and give the end user as much as the permissions will
|
|
// allow. If the user wanted to take something, they will select fewer
|
|
// and fewer items until only 'takeable' items are left. The one
|
|
// exception is if you own everything in the selection that is for
|
|
// sale, in this case, you can't buy stuff from yourself, so you can
|
|
// take it.
|
|
// return value = true if selection is a 'buy'.
|
|
// false if selection is a 'take'
|
|
bool is_selection_buy_not_take()
|
|
{
|
|
for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
|
|
iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
|
|
{
|
|
LLSelectNode* node = *iter;
|
|
LLViewerObject* obj = node->getObject();
|
|
if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale()))
|
|
{
|
|
// [RLVa:KB] - @buy
|
|
if (!RlvActions::canBuyObject(obj->getID()))
|
|
continue;
|
|
// [/RLVa:KB]
|
|
|
|
// you do not own the object and it is for sale, thus,
|
|
// it's a buy
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
S32 selection_price()
|
|
{
|
|
S32 total_price = 0;
|
|
for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
|
|
iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
|
|
{
|
|
LLSelectNode* node = *iter;
|
|
LLViewerObject* obj = node->getObject();
|
|
if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale()))
|
|
{
|
|
// you do not own the object and it is for sale.
|
|
// Add its price.
|
|
total_price += node->mSaleInfo.getSalePrice();
|
|
}
|
|
}
|
|
|
|
return total_price;
|
|
}
|
|
/*
|
|
bool callback_show_buy_currency(const LLSD& notification, const LLSD& response)
|
|
{
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
if (0 == option)
|
|
{
|
|
LL_INFOS() << "Loading page " << LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL") << LL_ENDL;
|
|
LLWeb::loadURL(LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL"));
|
|
}
|
|
return false;
|
|
}
|
|
*/
|
|
|
|
void show_buy_currency(const char* extra)
|
|
{
|
|
// Don't show currency web page for branded clients.
|
|
/*
|
|
std::ostringstream mesg;
|
|
if (extra != NULL)
|
|
{
|
|
mesg << extra << "\n \n";
|
|
}
|
|
mesg << "Go to " << LLNotifications::instance().getGlobalString("BUY_CURRENCY_URL")<< "\nfor information on purchasing currency?";
|
|
*/
|
|
LLSD args;
|
|
if (extra != NULL)
|
|
{
|
|
args["EXTRA"] = extra;
|
|
}
|
|
LLNotificationsUtil::add("PromptGoToCurrencyPage", args);//, LLSD(), callback_show_buy_currency);
|
|
}
|
|
|
|
void handle_buy()
|
|
{
|
|
if (LLSelectMgr::getInstance()->getSelection()->isEmpty()) return;
|
|
|
|
LLSaleInfo sale_info;
|
|
bool valid = LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info);
|
|
if (!valid) return;
|
|
|
|
S32 price = sale_info.getSalePrice();
|
|
|
|
if (price > 0 && price > gStatusBar->getBalance())
|
|
{
|
|
LLStringUtil::format_map_t args;
|
|
args["AMOUNT"] = llformat("%d", price);
|
|
LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("this_object_costs", args), price );
|
|
return;
|
|
}
|
|
|
|
if (sale_info.getSaleType() == LLSaleInfo::FS_CONTENTS)
|
|
{
|
|
handle_buy_contents(sale_info);
|
|
}
|
|
else
|
|
{
|
|
handle_buy_object(sale_info);
|
|
}
|
|
}
|
|
|
|
bool anyone_copy_selection(LLSelectNode* nodep)
|
|
{
|
|
bool perm_copy = (bool)(nodep->getObject()->permCopy());
|
|
bool all_copy = (bool)(nodep->mPermissions->getMaskEveryone() & PERM_COPY);
|
|
return perm_copy && all_copy;
|
|
}
|
|
|
|
bool for_sale_selection(LLSelectNode* nodep)
|
|
{
|
|
return nodep->mSaleInfo.isForSale()
|
|
&& nodep->mPermissions->getMaskOwner() & PERM_TRANSFER
|
|
&& (nodep->mPermissions->getMaskOwner() & PERM_COPY
|
|
|| nodep->mSaleInfo.getSaleType() != LLSaleInfo::FS_COPY);
|
|
}
|
|
|
|
bool sitting_on_selection()
|
|
{
|
|
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
|
|
if (!node)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!node->mValid)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
LLViewerObject* root_object = node->getObject();
|
|
if (!root_object)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Need to determine if avatar is sitting on this object
|
|
if (!isAgentAvatarValid()) return false;
|
|
|
|
return (gAgentAvatarp->isSitting() && gAgentAvatarp->getRoot() == root_object);
|
|
}
|
|
|
|
class LLToolsSaveToObjectInventory : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
|
|
if(node && (node->mValid) && (!node->mFromTaskID.isNull()))
|
|
{
|
|
// *TODO: check to see if the fromtaskid object exists.
|
|
derez_objects(DRD_SAVE_INTO_TASK_INVENTORY, node->mFromTaskID);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToolsEnablePathfinding : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion();
|
|
}
|
|
};
|
|
|
|
class LLToolsEnablePathfindingView : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return (LLPathfindingManager::getInstance() != NULL) && LLPathfindingManager::getInstance()->isPathfindingEnabledForCurrentRegion() && LLPathfindingManager::getInstance()->isPathfindingViewEnabled();
|
|
}
|
|
};
|
|
|
|
class LLToolsDoPathfindingRebakeRegion : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool hasPathfinding = (LLPathfindingManager::getInstance() != NULL);
|
|
|
|
if (hasPathfinding)
|
|
{
|
|
LLMenuOptionPathfindingRebakeNavmesh::getInstance()->sendRequestRebakeNavmesh();
|
|
}
|
|
|
|
return hasPathfinding;
|
|
}
|
|
};
|
|
|
|
class LLToolsEnablePathfindingRebakeRegion : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool returnValue = false;
|
|
|
|
if (LLNavigationBar::instanceExists())
|
|
{
|
|
returnValue = LLNavigationBar::getInstance()->isRebakeNavMeshAvailable();
|
|
}
|
|
return returnValue;
|
|
}
|
|
};
|
|
|
|
// Round the position of all root objects to the grid
|
|
class LLToolsSnapObjectXY : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
F64 snap_size = (F64)gSavedSettings.getF32("GridResolution");
|
|
|
|
for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
|
|
iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
|
|
{
|
|
LLSelectNode* node = *iter;
|
|
LLViewerObject* obj = node->getObject();
|
|
if (obj->permModify())
|
|
{
|
|
LLVector3d pos_global = obj->getPositionGlobal();
|
|
F64 round_x = fmod(pos_global.mdV[VX], snap_size);
|
|
if (round_x < snap_size * 0.5)
|
|
{
|
|
// closer to round down
|
|
pos_global.mdV[VX] -= round_x;
|
|
}
|
|
else
|
|
{
|
|
// closer to round up
|
|
pos_global.mdV[VX] -= round_x;
|
|
pos_global.mdV[VX] += snap_size;
|
|
}
|
|
|
|
F64 round_y = fmod(pos_global.mdV[VY], snap_size);
|
|
if (round_y < snap_size * 0.5)
|
|
{
|
|
pos_global.mdV[VY] -= round_y;
|
|
}
|
|
else
|
|
{
|
|
pos_global.mdV[VY] -= round_y;
|
|
pos_global.mdV[VY] += snap_size;
|
|
}
|
|
|
|
obj->setPositionGlobal(pos_global, false);
|
|
}
|
|
}
|
|
LLSelectMgr::getInstance()->sendMultipleUpdate(UPD_POSITION);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// Determine if the option to cycle between linked prims is shown
|
|
class LLToolsEnableSelectNextPart : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = (!LLSelectMgr::getInstance()->getSelection()->isEmpty()
|
|
&& (gSavedSettings.getBOOL("EditLinkedParts")
|
|
|| LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()));
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
// Cycle selection through linked children or/and faces in selected object.
|
|
// FIXME: Order of children list is not always the same as sim's idea of link order. This may confuse
|
|
// resis. Need link position added to sim messages to address this.
|
|
class LLToolsSelectNextPartFace : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool cycle_faces = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool();
|
|
bool cycle_linked = gSavedSettings.getBOOL("EditLinkedParts");
|
|
|
|
if (!cycle_faces && !cycle_linked)
|
|
{
|
|
// Nothing to do
|
|
return true;
|
|
}
|
|
|
|
bool fwd = (userdata.asString() == "next");
|
|
bool prev = (userdata.asString() == "previous");
|
|
bool ifwd = (userdata.asString() == "includenext");
|
|
bool iprev = (userdata.asString() == "includeprevious");
|
|
|
|
// <FS:Zi> Make shift+click on forward/back buttons work like includenext/previous
|
|
// (filter out the menu shortcuts by testing for ifwd / iprev)
|
|
if (gKeyboard->currentMask(false) & MASK_SHIFT && !ifwd && !iprev)
|
|
{
|
|
ifwd = fwd;
|
|
iprev = prev;
|
|
fwd = false;
|
|
prev = false;
|
|
}
|
|
// </FS:Zi>
|
|
|
|
LLViewerObject* to_select = NULL;
|
|
bool restart_face_on_part = !cycle_faces;
|
|
S32 new_te = 0;
|
|
|
|
if (cycle_faces)
|
|
{
|
|
// Cycle through faces of current selection, if end is reached, swithc to next part (if present)
|
|
LLSelectNode* nodep = LLSelectMgr::getInstance()->getSelection()->getFirstNode();
|
|
if (!nodep) return false;
|
|
to_select = nodep->getObject();
|
|
if (!to_select) return false;
|
|
|
|
S32 te_count = to_select->getNumTEs();
|
|
S32 selected_te = nodep->getLastOperatedTE();
|
|
|
|
if (fwd || ifwd)
|
|
{
|
|
// <FS:Zi> FIRE-32282: fix face selection cycle starting at face 1 instead of face 0
|
|
// is more than one face selected in the whole set?
|
|
if (LLSelectMgr::getInstance()->getSelection()->getTECount() > 1)
|
|
{
|
|
// count the number of selected faces on the current link
|
|
S32 count = 0;
|
|
S32 num_tes = to_select->getNumTEs();
|
|
for (S32 te = 0; te < num_tes; te++)
|
|
{
|
|
if (nodep->isTESelected(te))
|
|
{
|
|
++count;
|
|
}
|
|
}
|
|
|
|
// if all faces of the current link are selected, set a flag to make sure the
|
|
// next selected face will be face 0
|
|
if (count == num_tes)
|
|
{
|
|
selected_te = -1;
|
|
}
|
|
}
|
|
// </FS:Zi>
|
|
|
|
if (selected_te < 0)
|
|
{
|
|
new_te = 0;
|
|
}
|
|
else if (selected_te + 1 < te_count)
|
|
{
|
|
// select next face
|
|
new_te = selected_te + 1;
|
|
}
|
|
else
|
|
{
|
|
// restart from first face on next part
|
|
restart_face_on_part = true;
|
|
}
|
|
}
|
|
else if (prev || iprev)
|
|
{
|
|
if (selected_te > te_count)
|
|
{
|
|
new_te = te_count - 1;
|
|
}
|
|
else if (selected_te - 1 >= 0)
|
|
{
|
|
// select previous face
|
|
new_te = selected_te - 1;
|
|
}
|
|
else
|
|
{
|
|
// restart from last face on next part
|
|
restart_face_on_part = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
|
|
if (cycle_linked && object_count && restart_face_on_part)
|
|
{
|
|
LLViewerObject* selected = LLSelectMgr::getInstance()->getSelection()->getFirstObject();
|
|
if (selected && selected->getRootEdit())
|
|
{
|
|
LLViewerObject::child_list_t children = selected->getRootEdit()->getChildren();
|
|
children.push_front(selected->getRootEdit()); // need root in the list too
|
|
|
|
for (LLViewerObject::child_list_t::iterator iter = children.begin(); iter != children.end(); ++iter)
|
|
{
|
|
if ((*iter)->isSelected())
|
|
{
|
|
if (object_count > 1 && (fwd || prev)) // multiple selection, find first or last selected if not include
|
|
{
|
|
to_select = *iter;
|
|
if (fwd)
|
|
{
|
|
// stop searching if going forward; repeat to get last hit if backward
|
|
break;
|
|
}
|
|
}
|
|
else if ((object_count == 1) || (ifwd || iprev)) // single selection or include
|
|
{
|
|
if (fwd || ifwd)
|
|
{
|
|
++iter;
|
|
while (iter != children.end() && ((*iter)->isAvatar() || (ifwd && (*iter)->isSelected())))
|
|
{
|
|
++iter; // skip sitting avatars and selected if include
|
|
}
|
|
}
|
|
else // backward
|
|
{
|
|
iter = (iter == children.begin() ? children.end() : iter);
|
|
--iter;
|
|
while (iter != children.begin() && ((*iter)->isAvatar() || (iprev && (*iter)->isSelected())))
|
|
{
|
|
--iter; // skip sitting avatars and selected if include
|
|
}
|
|
}
|
|
iter = (iter == children.end() ? children.begin() : iter);
|
|
to_select = *iter;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (to_select)
|
|
{
|
|
if (gFocusMgr.childHasKeyboardFocus(gFloaterTools))
|
|
{
|
|
gFocusMgr.setKeyboardFocus(nullptr); // force edit toolbox to commit any changes
|
|
}
|
|
if (fwd || prev)
|
|
{
|
|
LLSelectMgr::getInstance()->deselectAll();
|
|
}
|
|
if (cycle_faces)
|
|
{
|
|
if (restart_face_on_part)
|
|
{
|
|
if (fwd || ifwd)
|
|
{
|
|
new_te = 0;
|
|
}
|
|
else
|
|
{
|
|
new_te = to_select->getNumTEs() - 1;
|
|
}
|
|
}
|
|
LLSelectMgr::getInstance()->selectObjectOnly(to_select, new_te);
|
|
LLSelectMgr::getInstance()->addAsIndividual(to_select, new_te, false);
|
|
}
|
|
else
|
|
{
|
|
LLSelectMgr::getInstance()->selectObjectOnly(to_select);
|
|
}
|
|
return true;
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToolsStopAllAnimations : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// <FS:Ansariel> Allow legacy stop animations without revoking script permissions
|
|
//gAgent.stopCurrentAnimations();
|
|
std::string param = userdata.asString();
|
|
if (param.empty() || param == "stoprevoke")
|
|
{
|
|
gAgent.stopCurrentAnimations();
|
|
}
|
|
else if (param == "stop")
|
|
{
|
|
gAgent.stopCurrentAnimations(true);
|
|
}
|
|
// </FS:Ansariel>
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToolsReleaseKeys : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-04-19 (RLVa-1.2.0f) | Modified: RLVa-1.0.5a
|
|
if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) )
|
|
return true;
|
|
// [/RLVa:KB]
|
|
|
|
gAgent.forceReleaseControls();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToolsEnableReleaseKeys : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-04-19 (RLVa-1.2.0f) | Modified: RLVa-1.0.5a
|
|
return (gAgent.anyControlGrabbed()) &&
|
|
( (!rlv_handler_t::isEnabled()) || (!gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) );
|
|
// [/RLVa:KB]
|
|
// return gAgent.anyControlGrabbed();
|
|
}
|
|
};
|
|
|
|
|
|
class LLEditEnableCut : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCut();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLEditCut : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (LLEditMenuHandler::gEditMenuHandler)
|
|
{
|
|
LLEditMenuHandler::gEditMenuHandler->cut();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLEditEnableCopy : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canCopy();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLEditCopy : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (LLEditMenuHandler::gEditMenuHandler)
|
|
{
|
|
LLEditMenuHandler::gEditMenuHandler->copy();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLEditEnablePaste : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canPaste();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLEditPaste : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (LLEditMenuHandler::gEditMenuHandler)
|
|
{
|
|
LLEditMenuHandler::gEditMenuHandler->paste();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLEditEnableDelete : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLEditDelete : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// If a text field can do a deletion, it gets precedence over deleting
|
|
// an object in the world.
|
|
if (LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDoDelete())
|
|
{
|
|
LLEditMenuHandler::gEditMenuHandler->doDelete();
|
|
}
|
|
|
|
// and close any pie/context menus when done
|
|
gMenuHolder->hideMenus();
|
|
|
|
// When deleting an object we may not actually be done
|
|
// Keep selection so we know what to delete when confirmation is needed about the delete
|
|
gMenuObject->hide();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
void handle_spellcheck_replace_with_suggestion(const LLUICtrl* ctrl, const LLSD& param)
|
|
{
|
|
const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
|
|
LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
|
|
if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
U32 index = 0;
|
|
if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
spellcheck_handler->replaceWithSuggestion(index);
|
|
}
|
|
|
|
bool visible_spellcheck_suggestion(LLUICtrl* ctrl, const LLSD& param)
|
|
{
|
|
LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(ctrl);
|
|
const LLContextMenu* menu = (item) ? dynamic_cast<const LLContextMenu*>(item->getParent()) : NULL;
|
|
const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
|
|
if ( (!spellcheck_handler) || (!spellcheck_handler->getSpellCheck()) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
U32 index = 0;
|
|
if ( (!LLStringUtil::convertToU32(param.asString(), index)) || (index >= spellcheck_handler->getSuggestionCount()) )
|
|
{
|
|
return false;
|
|
}
|
|
|
|
item->setLabel(spellcheck_handler->getSuggestion(index));
|
|
return true;
|
|
}
|
|
|
|
void handle_spellcheck_add_to_dictionary(const LLUICtrl* ctrl)
|
|
{
|
|
const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
|
|
LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
|
|
if ( (spellcheck_handler) && (spellcheck_handler->canAddToDictionary()) )
|
|
{
|
|
spellcheck_handler->addToDictionary();
|
|
}
|
|
}
|
|
|
|
bool enable_spellcheck_add_to_dictionary(const LLUICtrl* ctrl)
|
|
{
|
|
const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
|
|
const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
|
|
return (spellcheck_handler) && (spellcheck_handler->canAddToDictionary());
|
|
}
|
|
|
|
void handle_spellcheck_add_to_ignore(const LLUICtrl* ctrl)
|
|
{
|
|
const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
|
|
LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
|
|
if ( (spellcheck_handler) && (spellcheck_handler->canAddToIgnore()) )
|
|
{
|
|
spellcheck_handler->addToIgnore();
|
|
}
|
|
}
|
|
|
|
bool enable_spellcheck_add_to_ignore(const LLUICtrl* ctrl)
|
|
{
|
|
const LLContextMenu* menu = dynamic_cast<const LLContextMenu*>(ctrl->getParent());
|
|
const LLSpellCheckMenuHandler* spellcheck_handler = (menu) ? dynamic_cast<const LLSpellCheckMenuHandler*>(menu->getSpawningView()) : NULL;
|
|
return (spellcheck_handler) && (spellcheck_handler->canAddToIgnore());
|
|
}
|
|
|
|
bool enable_object_return()
|
|
{
|
|
return (!LLSelectMgr::getInstance()->getSelection()->isEmpty() &&
|
|
(gAgent.isGodlike() || can_derez(DRD_RETURN_TO_OWNER)));
|
|
}
|
|
|
|
bool enable_object_delete()
|
|
{
|
|
bool new_value =
|
|
#ifdef HACKED_GODLIKE_VIEWER
|
|
true;
|
|
#else
|
|
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
|
|
(LLGridManager::getInstance()->isInSLBeta()
|
|
&& gAgent.isGodlike()) ||
|
|
# endif
|
|
LLSelectMgr::getInstance()->canDoDelete();
|
|
#endif
|
|
return new_value;
|
|
}
|
|
|
|
class LLObjectsReturnPackage
|
|
{
|
|
public:
|
|
LLObjectsReturnPackage() : mObjectSelection(), mReturnableObjects(), mError(), mFirstRegion(nullptr) {};
|
|
~LLObjectsReturnPackage()
|
|
{
|
|
mObjectSelection.clear();
|
|
mReturnableObjects.clear();
|
|
mError.clear();
|
|
mFirstRegion = NULL;
|
|
};
|
|
|
|
LLObjectSelectionHandle mObjectSelection;
|
|
std::vector<LLViewerObjectPtr> mReturnableObjects;
|
|
std::string mError;
|
|
LLViewerRegion *mFirstRegion;
|
|
};
|
|
|
|
static void return_objects(LLObjectsReturnPackage *objectsReturnPackage, const LLSD& notification, const LLSD& response)
|
|
{
|
|
if (LLNotificationsUtil::getSelectedOption(notification, response) == 0)
|
|
{
|
|
// Ignore category ID for this derez destination.
|
|
derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null, objectsReturnPackage->mFirstRegion, objectsReturnPackage->mError, &objectsReturnPackage->mReturnableObjects);
|
|
}
|
|
|
|
delete objectsReturnPackage;
|
|
}
|
|
|
|
void handle_object_return()
|
|
{
|
|
if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
|
|
{
|
|
LLObjectsReturnPackage *objectsReturnPackage = new LLObjectsReturnPackage();
|
|
objectsReturnPackage->mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
|
|
|
|
// Save selected objects, so that we still know what to return after the confirmation dialog resets selection.
|
|
get_derezzable_objects(DRD_RETURN_TO_OWNER, objectsReturnPackage->mError, objectsReturnPackage->mFirstRegion, &objectsReturnPackage->mReturnableObjects);
|
|
|
|
LLNotificationsUtil::add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&return_objects, objectsReturnPackage, _1, _2));
|
|
}
|
|
}
|
|
|
|
void handle_object_delete()
|
|
{
|
|
|
|
if (LLSelectMgr::getInstance())
|
|
{
|
|
LLSelectMgr::getInstance()->doDelete();
|
|
}
|
|
|
|
// and close any pie/context menus when done
|
|
gMenuHolder->hideMenus();
|
|
|
|
// When deleting an object we may not actually be done
|
|
// Keep selection so we know what to delete when confirmation is needed about the delete
|
|
gMenuObject->hide();
|
|
return;
|
|
}
|
|
|
|
void handle_force_delete()
|
|
{
|
|
LLSelectMgr::getInstance()->selectForceDelete();
|
|
}
|
|
|
|
class LLViewEnableJoystickFlycam : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = (gSavedSettings.getBOOL("JoystickEnabled") && gSavedSettings.getBOOL("JoystickFlycamEnabled"));
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLViewEnableLastChatter : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// *TODO: add check that last chatter is in range
|
|
bool new_value = (gAgentCamera.cameraThirdPerson() && gAgent.getLastChatter().notNull());
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLEditEnableDeselect : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDeselect();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLEditDeselect : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if( LLEditMenuHandler::gEditMenuHandler )
|
|
{
|
|
LLEditMenuHandler::gEditMenuHandler->deselect();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLEditEnableSelectAll : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canSelectAll();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
class LLEditSelectAll : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if( LLEditMenuHandler::gEditMenuHandler )
|
|
{
|
|
LLEditMenuHandler::gEditMenuHandler->selectAll();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
class LLEditEnableUndo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLEditUndo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canUndo() )
|
|
{
|
|
LLEditMenuHandler::gEditMenuHandler->undo();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLEditEnableRedo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLEditRedo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if( LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canRedo() )
|
|
{
|
|
LLEditMenuHandler::gEditMenuHandler->redo();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
void print_object_info()
|
|
{
|
|
LLSelectMgr::getInstance()->selectionDump();
|
|
}
|
|
|
|
void print_agent_nvpairs()
|
|
{
|
|
LLViewerObject *objectp;
|
|
|
|
LL_INFOS() << "Agent Name Value Pairs" << LL_ENDL;
|
|
|
|
objectp = gObjectList.findObject(gAgentID);
|
|
if (objectp)
|
|
{
|
|
objectp->printNameValuePairs();
|
|
}
|
|
else
|
|
{
|
|
LL_INFOS() << "Can't find agent object" << LL_ENDL;
|
|
}
|
|
|
|
LL_INFOS() << "Camera at " << gAgentCamera.getCameraPositionGlobal() << LL_ENDL;
|
|
}
|
|
|
|
void show_debug_menus()
|
|
{
|
|
// this might get called at login screen where there is no menu so only toggle it if one exists
|
|
if ( gMenuBarView )
|
|
{
|
|
bool debug = gSavedSettings.getBOOL("UseDebugMenus");
|
|
bool qamode = gSavedSettings.getBOOL("QAMode");
|
|
|
|
gMenuBarView->setItemVisible("Advanced", debug);
|
|
// gMenuBarView->setItemEnabled("Advanced", debug); // Don't disable Advanced keyboard shortcuts when hidden
|
|
|
|
// [RLVa:KB] - Checked: 2011-08-16 (RLVa-1.4.0b) | Modified: RLVa-1.4.0b
|
|
// NOTE: this is supposed to execute whether RLVa is enabled or not
|
|
rlvMenuToggleVisible();
|
|
// [/RLVa:KB]
|
|
|
|
gMenuBarView->setItemVisible("Debug", qamode);
|
|
gMenuBarView->setItemEnabled("Debug", qamode);
|
|
|
|
gMenuBarView->setItemVisible("Develop", qamode);
|
|
gMenuBarView->setItemEnabled("Develop", qamode);
|
|
|
|
// Server ('Admin') menu hidden when not in godmode.
|
|
const bool show_server_menu = (gAgent.getGodLevel() > GOD_NOT || (debug && gAgent.getAdminOverride()));
|
|
gMenuBarView->setItemVisible("Admin", show_server_menu);
|
|
gMenuBarView->setItemEnabled("Admin", show_server_menu);
|
|
}
|
|
if (gLoginMenuBarView)
|
|
{
|
|
bool debug = gSavedSettings.getBOOL("UseDebugMenus");
|
|
gLoginMenuBarView->setItemVisible("Debug", debug);
|
|
gLoginMenuBarView->setItemEnabled("Debug", debug);
|
|
}
|
|
}
|
|
|
|
void toggle_debug_menus()
|
|
{
|
|
bool visible = ! gSavedSettings.getBOOL("UseDebugMenus");
|
|
gSavedSettings.setBOOL("UseDebugMenus", visible);
|
|
show_debug_menus();
|
|
}
|
|
|
|
// <FS:Ansariel> [FS Communication UI]
|
|
//class LLCommunicateNearbyChat : public view_listener_t
|
|
//{
|
|
// bool handleEvent(const LLSD& userdata)
|
|
// {
|
|
// LLFloaterIMContainer* im_box = LLFloaterIMContainer::getInstance();
|
|
// LLFloaterIMNearbyChat* floater_nearby = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
|
|
// if (floater_nearby->isInVisibleChain() && !floater_nearby->isTornOff()
|
|
// && im_box->getSelectedSession() == LLUUID() && im_box->getConversationListItemSize() > 1)
|
|
// {
|
|
// im_box->selectNextorPreviousConversation(false);
|
|
// }
|
|
// else
|
|
// {
|
|
// LLFloaterReg::toggleInstanceOrBringToFront("nearby_chat");
|
|
// }
|
|
// return true;
|
|
// }
|
|
//};
|
|
// </FS:Ansariel> [FS Communication UI]
|
|
|
|
class LLWorldSetHomeLocation : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// we just send the message and let the server check for failure cases
|
|
// server will echo back a "Home position set." alert if it succeeds
|
|
// and the home location screencapture happens when that alert is recieved
|
|
gAgent.setStartPosition(START_LOCATION_ID_HOME);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLWorldLindenHome : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string url = LLFloaterLandHoldings::sHasLindenHome ? LLTrans::getString("lindenhomes_my_home_url") : LLTrans::getString("lindenhomes_get_home_url");
|
|
LLWeb::loadURL(url);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLWorldTeleportHome : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gAgent.teleportHome();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLWorldAlwaysRun : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// as well as altering the default walk-vs-run state,
|
|
// we also change the *current* walk-vs-run state.
|
|
if (gAgent.getAlwaysRun())
|
|
{
|
|
gAgent.clearAlwaysRun();
|
|
// gAgent.clearRunning();
|
|
FSCommon::report_to_nearby_chat(LLTrans::getString("AlwaysRunDisabled"));
|
|
}
|
|
else
|
|
{
|
|
gAgent.setAlwaysRun();
|
|
// gAgent.setRunning();
|
|
FSCommon::report_to_nearby_chat(LLTrans::getString("AlwaysRunEnabled"));
|
|
}
|
|
|
|
// tell the simulator.
|
|
// gAgent.sendWalkRun(gAgent.getAlwaysRun());
|
|
|
|
// Update Movement Controls according to AlwaysRun mode
|
|
LLFloaterMove::setAlwaysRunMode(gAgent.getAlwaysRun());
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLWorldCheckAlwaysRun : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gAgent.getAlwaysRun();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLWorldSetAway : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (gAgent.getAFK())
|
|
{
|
|
gAgent.clearAFK();
|
|
}
|
|
else
|
|
{
|
|
gAgent.setAFK();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
// [SJ - FIRE-2177 - Making Autorespons a simple Check in the menu again for clarity]
|
|
class LLWorldGetAway : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gAgent.getAFK();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLWorldSetDoNotDisturb : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (gAgent.isDoNotDisturb())
|
|
{
|
|
gAgent.setDoNotDisturb(false);
|
|
}
|
|
else
|
|
{
|
|
gAgent.setDoNotDisturb(true);
|
|
LLNotificationsUtil::add("DoNotDisturbModeSet");
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// <FS:minerjr> [FIRE-35039] Add flag to show/hide the on-screen console
|
|
// View Listener class to toggle the saved settings value FSShowOnscreenConsole
|
|
class LLCommSetShowOnscreenConsole : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// Toggle the value to the opposite and just save the value back to the settings.
|
|
// This change will propagate to the other controls for this value
|
|
bool show_onscreen_console = !gSavedSettings.getBOOL("FSShowOnscreenConsole");
|
|
gSavedSettings.setBOOL("FSShowOnscreenConsole", show_onscreen_console);
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// View Listener class to retrieve the saved settings value FSShowOnscreenConsole
|
|
class LLCommCheckShowOnscreenConsole : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// Retrieve the Show On-screen Console flag and return it the the UI to update the state of the menu toggle.
|
|
bool show_onscreen_console = gSavedSettings.getBOOL("FSShowOnscreenConsole");
|
|
return show_onscreen_console;
|
|
}
|
|
};
|
|
// </FS:minerjr> [FIRE-35039]
|
|
|
|
// [SJ - FIRE-2177 - Making Autorespons a simple Check in the menu again for clarity]
|
|
class LLWorldGetBusy : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gAgent.isDoNotDisturb();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
class LLWorldSetAutorespond : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (gAgent.getAutorespond())
|
|
{
|
|
gAgent.clearAutorespond();
|
|
}
|
|
else
|
|
{
|
|
gAgent.setAutorespond();
|
|
LLNotificationsUtil::add("AutorespondModeSet");
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// [SJ - FIRE-2177 - Making Autorespons a simple Check in the menu again for clarity]
|
|
class LLWorldGetAutorespond : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gAgent.getAutorespond();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
|
|
class LLWorldSetAutorespondNonFriends : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (gAgent.getAutorespondNonFriends())
|
|
{
|
|
gAgent.clearAutorespondNonFriends();
|
|
}
|
|
else
|
|
{
|
|
gAgent.setAutorespondNonFriends();
|
|
LLNotificationsUtil::add("AutorespondNonFriendsModeSet");
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// [SJ - FIRE-2177 - Making Autorespons a simple Check in the menu again for clarity]
|
|
class LLWorldGetAutorespondNonFriends : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gAgent.getAutorespondNonFriends();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
// <FS:PP> FIRE-1245: Option to block/reject teleport offers
|
|
class LLWorldSetRejectTeleportOffers : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (gAgent.getRejectTeleportOffers())
|
|
{
|
|
gAgent.clearRejectTeleportOffers();
|
|
}
|
|
else
|
|
{
|
|
gAgent.setRejectTeleportOffers();
|
|
LLNotificationsUtil::add("RejectTeleportOffersModeSet");
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// [SJ - FIRE-2177 - Making Autorespons a simple Check in the menu again for clarity]
|
|
class LLWorldGetRejectTeleportOffers : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gAgent.getRejectTeleportOffers();
|
|
return new_value;
|
|
}
|
|
};
|
|
// </FS:PP> FIRE-1245: Option to block/reject teleport offers
|
|
|
|
// <FS:PP> FIRE-15233: Automatic friendship request refusal
|
|
class LLWorldSetRejectFriendshipRequests : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (gAgent.getRejectFriendshipRequests())
|
|
{
|
|
gAgent.clearRejectFriendshipRequests();
|
|
}
|
|
else
|
|
{
|
|
gAgent.setRejectFriendshipRequests();
|
|
LLNotificationsUtil::add("RejectFriendshipRequestsModeSet");
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// [SJ - FIRE-2177 - Making Autorespons a simple Check in the menu again for clarity]
|
|
class LLWorldGetRejectFriendshipRequests : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gAgent.getRejectFriendshipRequests();
|
|
return new_value;
|
|
}
|
|
};
|
|
// </FS:PP> FIRE-15233: Automatic friendship request refusal
|
|
|
|
// <FS:PP> Option to block/reject all group invites
|
|
class LLWorldSetRejectAllGroupInvites : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (gAgent.getRejectAllGroupInvites())
|
|
{
|
|
gAgent.clearRejectAllGroupInvites();
|
|
}
|
|
else
|
|
{
|
|
gAgent.setRejectAllGroupInvites();
|
|
LLNotificationsUtil::add("RejectAllGroupInvitesModeSet");
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// [SJ - FIRE-2177 - Making Autorespons a simple Check in the menu again for clarity]
|
|
class LLWorldGetRejectAllGroupInvites : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gAgent.getRejectAllGroupInvites();
|
|
return new_value;
|
|
}
|
|
};
|
|
// </FS:PP> Option to block/reject all group invites
|
|
|
|
class LLWorldCreateLandmark : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.4.5) | Added: RLVa-1.0.0
|
|
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
|
|
return true;
|
|
// [/RLVa:KB]
|
|
|
|
LLFloaterReg::showInstance("add_landmark");
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLWorldPlaceProfile : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5
|
|
if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
|
|
return true;
|
|
// [/RLVa:KB]
|
|
|
|
// <FS:Ansariel> FIRE-817: Separate place details floater
|
|
//LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "agent"));
|
|
FSFloaterPlaceDetails::showPlaceDetails(LLSD().with("type", "agent"));
|
|
// </FS:Ansariel>
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5
|
|
bool enable_place_profile()
|
|
{
|
|
return LLFloaterSidePanelContainer::canShowPanel("places", LLSD().with("type", "agent"));
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
void handle_script_info()
|
|
{
|
|
LLUUID object_id;
|
|
if (LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())
|
|
{
|
|
object_id = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->mID;
|
|
LL_INFOS() << "Reporting Script Info for object: " << object_id.asString() << LL_ENDL;
|
|
FSLSLBridge::instance().viewerToLSL("getScriptInfo|" + object_id.asString() + "|" + (gSavedSettings.getBOOL("FSScriptInfoExtended") ? "1" : "0"));
|
|
}
|
|
}
|
|
|
|
void handle_look_at_selection(const LLSD& param)
|
|
{
|
|
const F32 PADDING_FACTOR = 1.75f;
|
|
bool zoom = (param.asString() == "zoom");
|
|
if (!LLSelectMgr::getInstance()->getSelection()->isEmpty())
|
|
{
|
|
gAgentCamera.setFocusOnAvatar(false, ANIMATE);
|
|
|
|
LLBBox selection_bbox = LLSelectMgr::getInstance()->getBBoxOfSelection();
|
|
F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView());
|
|
F32 distance = selection_bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view);
|
|
|
|
LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - selection_bbox.getCenterAgent();
|
|
obj_to_cam.normVec();
|
|
|
|
LLUUID object_id;
|
|
if (LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())
|
|
{
|
|
object_id = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()->mID;
|
|
}
|
|
if (zoom)
|
|
{
|
|
// Make sure we are not increasing the distance between the camera and object
|
|
LLVector3d orig_distance = gAgentCamera.getCameraPositionGlobal() - LLSelectMgr::getInstance()->getSelectionCenterGlobal();
|
|
distance = llmin(distance, (F32) orig_distance.length());
|
|
|
|
gAgentCamera.setCameraPosAndFocusGlobal(LLSelectMgr::getInstance()->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance),
|
|
LLSelectMgr::getInstance()->getSelectionCenterGlobal(),
|
|
object_id );
|
|
|
|
}
|
|
else
|
|
{
|
|
gAgentCamera.setFocusGlobal( LLSelectMgr::getInstance()->getSelectionCenterGlobal(), object_id );
|
|
}
|
|
}
|
|
}
|
|
|
|
// <FS:Ansariel> Option to try via exact position
|
|
//void handle_zoom_to_object(const LLUUID& object_id)
|
|
void handle_zoom_to_object(const LLUUID& object_id, const LLVector3d& object_pos)
|
|
// </FS:Ansariel> Option to try via exact position
|
|
{
|
|
// <FS:Zi> Fix camera zoom to look at the avatar's face from the front
|
|
// const F32 PADDING_FACTOR = 2.f;
|
|
// </FS:Zi>
|
|
|
|
LLViewerObject* object = gObjectList.findObject(object_id);
|
|
|
|
if (object)
|
|
{
|
|
gAgentCamera.setFocusOnAvatar(false, ANIMATE);
|
|
|
|
// <FS:Zi> Fix camera zoom to look at the avatar's face from the front
|
|
// LLBBox bbox = object->getBoundingBoxAgent() ;
|
|
// F32 angle_of_view = llmax(0.1f, LLViewerCamera::getInstance()->getAspect() > 1.f ? LLViewerCamera::getInstance()->getView() * LLViewerCamera::getInstance()->getAspect() : LLViewerCamera::getInstance()->getView());
|
|
// F32 distance = bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view);
|
|
|
|
// LLVector3 obj_to_cam = LLViewerCamera::getInstance()->getOrigin() - bbox.getCenterAgent();
|
|
// obj_to_cam.normVec();
|
|
|
|
|
|
// LLVector3d object_center_global = gAgent.getPosGlobalFromAgent(bbox.getCenterAgent());
|
|
|
|
// gAgentCamera.setCameraPosAndFocusGlobal(object_center_global + LLVector3d(obj_to_cam * distance),
|
|
// object_center_global,
|
|
|
|
LLVector3d object_center_global=object->getPositionGlobal();
|
|
|
|
float eye_distance=gSavedSettings.getF32("CameraZoomDistance");
|
|
float eye_z_offset=gSavedSettings.getF32("CameraZoomEyeZOffset");
|
|
LLVector3d focus_z_offset=LLVector3d(0.0f,0.0f,gSavedSettings.getF32("CameraZoomFocusZOffset"));
|
|
|
|
LLVector3d eye_offset(eye_distance,0.0f,eye_z_offset);
|
|
eye_offset=eye_offset*object->getRotationRegion();
|
|
|
|
gAgentCamera.setCameraPosAndFocusGlobal(object_center_global+eye_offset,
|
|
object_center_global+focus_z_offset,
|
|
// </FS:Zi>
|
|
object_id );
|
|
}
|
|
// <FS:Ansariel> Option to try via exact position
|
|
else if (object_pos != LLVector3d(-1.f, -1.f, -1.f))
|
|
{
|
|
LLVector3d obj_to_cam = object_pos - gAgent.getPositionGlobal();
|
|
obj_to_cam.normVec();
|
|
obj_to_cam = obj_to_cam * -4.f;
|
|
obj_to_cam.mdV[VZ] += 0.5;
|
|
|
|
gAgentCamera.changeCameraToThirdPerson();
|
|
gAgentCamera.unlockView();
|
|
gAgentCamera.setCameraPosAndFocusGlobal(object_pos + obj_to_cam, object_pos, object_id);
|
|
}
|
|
// </FS:Ansariel> Option to try via exact position
|
|
}
|
|
|
|
class LLAvatarInviteToGroup : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
|
// if(avatar)
|
|
// [RLVa:KB] - Checked: RLVa-1.2.0
|
|
if ( (avatar) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) )
|
|
// [/RLVa:KB]
|
|
{
|
|
LLAvatarActions::inviteToGroup(avatar->getID());
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAvatarAddFriend : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
|
// if(avatar && !LLAvatarActions::isFriend(avatar->getID()))
|
|
// [RLVa:KB] - Checked: RLVa-1.2.0
|
|
if ( (avatar && !LLAvatarActions::isFriend(avatar->getID())) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) )
|
|
// [/RLVa:KB]
|
|
{
|
|
request_friendship(avatar->getID());
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
class LLAvatarToggleMyProfile : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLFloater* instance = LLAvatarActions::getProfileFloater(gAgent.getID());
|
|
if (LLFloater::isMinimized(instance))
|
|
{
|
|
instance->setMinimized(false);
|
|
instance->setFocus(true);
|
|
}
|
|
else if (!LLFloater::isShown(instance))
|
|
{
|
|
LLAvatarActions::showProfile(gAgent.getID());
|
|
}
|
|
else if (!instance->hasFocus() && !instance->getIsChrome())
|
|
{
|
|
instance->setFocus(true);
|
|
}
|
|
else
|
|
{
|
|
instance->closeFloater();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAvatarTogglePicks : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLFloater * instance = LLAvatarActions::getProfileFloater(gAgent.getID());
|
|
if (LLFloater::isMinimized(instance) || (instance && !instance->hasFocus() && !instance->getIsChrome()))
|
|
{
|
|
instance->setMinimized(false);
|
|
instance->setFocus(true);
|
|
LLAvatarActions::showPicks(gAgent.getID());
|
|
}
|
|
else if (picks_tab_visible())
|
|
{
|
|
instance->closeFloater();
|
|
}
|
|
else
|
|
{
|
|
LLAvatarActions::showPicks(gAgent.getID());
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAvatarToggleSearch : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLFloater* instance = LLFloaterReg::findInstance("search");
|
|
if (LLFloater::isMinimized(instance))
|
|
{
|
|
instance->setMinimized(false);
|
|
instance->setFocus(true);
|
|
}
|
|
else if (!LLFloater::isShown(instance))
|
|
{
|
|
LLFloaterReg::showInstance("search");
|
|
}
|
|
else if (!instance->hasFocus() && !instance->getIsChrome())
|
|
{
|
|
instance->setFocus(true);
|
|
}
|
|
else
|
|
{
|
|
instance->closeFloater();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAvatarResetSkeleton : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()))
|
|
{
|
|
avatar->resetSkeleton(false);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAvatarEnableResetSkeleton : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
|
|
class LLAvatarResetSkeletonAndAnimations : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()))
|
|
{
|
|
avatar->resetSkeleton(true);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAvatarResetSelfSkeleton : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()))
|
|
{
|
|
avatar->resetSkeleton(false);
|
|
}
|
|
else
|
|
{
|
|
gAgentAvatarp->resetSkeleton(false);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAvatarResetSelfSkeletonAndAnimations : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject()))
|
|
{
|
|
avatar->resetSkeleton(true);
|
|
}
|
|
else
|
|
{
|
|
gAgentAvatarp->resetSkeleton(true);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAvatarAddContact : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
|
// if(avatar)
|
|
// [RLVa:KB] - Checked: RLVa-1.2.0
|
|
if ( (avatar) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) )
|
|
// [/RLVa:KB]
|
|
{
|
|
create_inventory_callingcard(avatar->getID());
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle selection)
|
|
{
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
if (option == 0)
|
|
{
|
|
gAgent.setDoNotDisturb(false);
|
|
}
|
|
|
|
LLViewerObject* objectp = selection->getPrimaryObject();
|
|
|
|
// Show avatar's name if paying attachment
|
|
if (objectp && objectp->isAttachment())
|
|
{
|
|
while (objectp && !objectp->isAvatar())
|
|
{
|
|
objectp = (LLViewerObject*)objectp->getParent();
|
|
}
|
|
}
|
|
|
|
if (objectp)
|
|
{
|
|
if (objectp->isAvatar())
|
|
{
|
|
const bool is_group = false;
|
|
LLFloaterPayUtil::payDirectly(&give_money,
|
|
objectp->getID(),
|
|
is_group);
|
|
}
|
|
else
|
|
{
|
|
LLFloaterPayUtil::payViaObject(&give_money, selection);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void handle_give_money_dialog()
|
|
{
|
|
LLNotification::Params params("DoNotDisturbModePay");
|
|
params.functor.function(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection()));
|
|
|
|
if (gAgent.isDoNotDisturb())
|
|
{
|
|
// warn users of being in do not disturb mode during a transaction
|
|
LLNotifications::instance().add(params);
|
|
}
|
|
else
|
|
{
|
|
LLNotifications::instance().forceResponse(params, 1);
|
|
}
|
|
}
|
|
|
|
bool enable_pay_avatar()
|
|
{
|
|
LLViewerObject* obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
LLVOAvatar* avatar = find_avatar_from_object(obj);
|
|
// return (avatar != NULL);
|
|
// [RLVa:KB] - @shownames and @pay
|
|
return (avatar != NULL) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) && (RlvActions::canPayAvatar(avatar->getID()));
|
|
// [/RLVa:KB]
|
|
}
|
|
|
|
bool enable_pay_object()
|
|
{
|
|
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if( object )
|
|
{
|
|
LLViewerObject *parent = (LLViewerObject *)object->getParent();
|
|
if((object->flagTakesMoney()) || (parent && parent->flagTakesMoney()))
|
|
{
|
|
// [RLVa:KB] - @buy
|
|
return RlvActions::canBuyObject(object->getID());
|
|
// [/RLVa:KB]
|
|
// return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool enable_object_stand_up()
|
|
{
|
|
// 'Object Stand Up' menu item is enabled when agent is sitting on selection
|
|
// return sitting_on_selection();
|
|
// [RLVa:KB] - Checked: 2010-07-24 (RLVa-1.2.0g) | Added: RLVa-1.2.0g
|
|
return sitting_on_selection() && ( (!rlv_handler_t::isEnabled()) || (RlvActions::canStand()) );
|
|
// [/RLVa:KB]
|
|
}
|
|
|
|
bool enable_object_sit(LLUICtrl* ctrl)
|
|
{
|
|
// 'Object Sit' menu item is enabled when agent is not sitting on selection
|
|
bool sitting_on_sel = sitting_on_selection();
|
|
if (!sitting_on_sel)
|
|
{
|
|
// init default labels
|
|
init_default_item_label(ctrl);
|
|
|
|
// Update label
|
|
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
|
|
if (node && node->mValid && !node->mSitName.empty())
|
|
{
|
|
ctrl->setValue(node->mSitName);
|
|
}
|
|
else
|
|
{
|
|
ctrl->setValue(get_default_item_label(ctrl->getName()));
|
|
}
|
|
}
|
|
|
|
// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.2.0c) | Modified: RLVa-1.2.0c
|
|
// RELEASE-RLVA: [SL-2.2.0] Make this match what happens in handle_object_sit_or_stand()
|
|
if (rlv_handler_t::isEnabled())
|
|
{
|
|
const LLPickInfo& pick = LLToolPie::getInstance()->getPick();
|
|
if (pick.mObjectID.notNull())
|
|
sitting_on_sel = !RlvActions::canSit(pick.getObject(), pick.mObjectOffset);
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
return !sitting_on_sel && is_object_sittable();
|
|
}
|
|
|
|
void dump_select_mgr()
|
|
{
|
|
LLSelectMgr::getInstance()->dump();
|
|
}
|
|
|
|
void dump_inventory()
|
|
{
|
|
gInventory.dumpInventory();
|
|
}
|
|
|
|
|
|
void handle_dump_followcam()
|
|
{
|
|
LLFollowCamMgr::getInstance()->dump();
|
|
}
|
|
|
|
void handle_viewer_enable_message_log()
|
|
{
|
|
gMessageSystem->startLogging();
|
|
}
|
|
|
|
void handle_viewer_disable_message_log()
|
|
{
|
|
gMessageSystem->stopLogging();
|
|
}
|
|
|
|
void handle_customize_avatar()
|
|
{
|
|
// <FS:Ansariel> FIRE-19614: Make CTRL-O toggle the appearance floater
|
|
LLFloater* floater = LLFloaterReg::findInstance("appearance");
|
|
if (floater && floater->isMinimized())
|
|
{
|
|
floater->setMinimized(false);
|
|
}
|
|
else if (LLFloater::isShown(floater))
|
|
{
|
|
LLFloaterReg::hideInstance("appearance");
|
|
}
|
|
else
|
|
// </FS:Ansariel>
|
|
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "my_outfits"));
|
|
}
|
|
|
|
void handle_edit_outfit()
|
|
{
|
|
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
|
|
}
|
|
|
|
void handle_now_wearing()
|
|
{
|
|
LLSidepanelAppearance *panel_appearance = dynamic_cast<LLSidepanelAppearance *>(LLFloaterSidePanelContainer::getPanel("appearance"));
|
|
if (panel_appearance && panel_appearance->isInVisibleChain() && panel_appearance->isCOFPanelVisible())
|
|
{
|
|
LLFloaterReg::findInstance("appearance")->closeFloater();
|
|
return;
|
|
}
|
|
|
|
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "now_wearing"));
|
|
}
|
|
|
|
void handle_edit_shape()
|
|
{
|
|
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_shape"));
|
|
}
|
|
|
|
void handle_hover_height()
|
|
{
|
|
LLFloaterReg::showInstance("edit_hover_height");
|
|
}
|
|
|
|
void handle_edit_physics()
|
|
{
|
|
LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_physics"));
|
|
}
|
|
|
|
void handle_report_abuse()
|
|
{
|
|
// Prevent menu from appearing in screen shot.
|
|
gMenuHolder->hideMenus();
|
|
LLFloaterReporter::showFromMenu(COMPLAINT_REPORT);
|
|
}
|
|
|
|
void handle_buy_currency()
|
|
{
|
|
LLBuyCurrencyHTML::openCurrencyFloater();
|
|
}
|
|
|
|
void handle_recreate_lsl_bridge()
|
|
{
|
|
FSLSLBridge::instance().recreateBridge();
|
|
}
|
|
|
|
class LLFloaterVisible : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string floater_name = userdata.asString();
|
|
bool new_value = false;
|
|
{
|
|
new_value = LLFloaterReg::instanceVisible(floater_name);
|
|
}
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLShowHelp : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string help_topic = userdata.asString();
|
|
#ifdef OPENSIM
|
|
if (help_topic.find("grid_") != std::string::npos)
|
|
{
|
|
help_topic.erase(0,5);
|
|
|
|
std::string url;
|
|
LLSD grid_info;
|
|
LLGridManager::getInstance()->getGridData(grid_info);
|
|
if (grid_info.has(help_topic))
|
|
{
|
|
url = grid_info[help_topic].asString();
|
|
}
|
|
|
|
if(!url.empty())
|
|
{
|
|
LLWeb::loadURLInternal(url);
|
|
}
|
|
LL_DEBUGS() << "grid_help " << help_topic << " url " << url << LL_ENDL;
|
|
|
|
return true;
|
|
}
|
|
#endif // OPENSIM
|
|
LLViewerHelp* vhelp = LLViewerHelp::getInstance();
|
|
vhelp->showTopic(help_topic);
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// <AW: OpenSim>
|
|
bool update_grid_help()
|
|
{
|
|
// <FS:AW grid management>
|
|
if (!gMenuHolder) //defend crash on shutdown
|
|
{
|
|
return false;
|
|
}
|
|
// </FS:AW grid management>
|
|
|
|
bool needs_seperator = false;
|
|
|
|
#ifdef OPENSIM // <FS:AW optional opensim support>
|
|
LLSD grid_info;
|
|
LLGridManager::getInstance()->getGridData(grid_info);
|
|
std::string grid_label = LLGridManager::getInstance()->getGridLabel();
|
|
bool is_opensim = LLGridManager::getInstance()->isInOpenSim();
|
|
if (is_opensim && grid_info.has("help"))
|
|
{
|
|
needs_seperator = true;
|
|
gMenuHolder->childSetVisible("current_grid_help",true);
|
|
gMenuHolder->childSetLabelArg("current_grid_help", "[CURRENT_GRID]", grid_label);
|
|
gMenuHolder->childSetVisible("current_grid_help_login",true);
|
|
gMenuHolder->childSetLabelArg("current_grid_help_login", "[CURRENT_GRID]", grid_label);
|
|
}
|
|
else
|
|
#endif // OPENSIM // <FS:AW optional opensim support>
|
|
{
|
|
gMenuHolder->childSetVisible("current_grid_help",false);
|
|
gMenuHolder->childSetVisible("current_grid_help_login",false);
|
|
}
|
|
#ifdef OPENSIM // <FS:AW optional opensim support>
|
|
if (is_opensim && grid_info.has("about"))
|
|
{
|
|
needs_seperator = true;
|
|
gMenuHolder->childSetVisible("current_grid_about",true);
|
|
gMenuHolder->childSetLabelArg("current_grid_about", "[CURRENT_GRID]", grid_label);
|
|
gMenuHolder->childSetVisible("current_grid_about_login",true);
|
|
gMenuHolder->childSetLabelArg("current_grid_about_login", "[CURRENT_GRID]", grid_label);
|
|
}
|
|
else
|
|
#endif // OPENSIM // <FS:AW optional opensim support>
|
|
{
|
|
gMenuHolder->childSetVisible("current_grid_about",false);
|
|
gMenuHolder->childSetVisible("current_grid_about_login",false);
|
|
}
|
|
//FIXME: this does nothing
|
|
gMenuHolder->childSetVisible("grid_help_seperator",needs_seperator);
|
|
gMenuHolder->childSetVisible("grid_help_seperator_login",needs_seperator);
|
|
|
|
// <FS:AW opensim destinations and avatar picker>
|
|
#ifdef OPENSIM // <FS:AW optional opensim support>
|
|
if (is_opensim)
|
|
{
|
|
if (!LLLoginInstance::getInstance()->hasResponse("destination_guide_url")
|
|
||LLLoginInstance::getInstance()->getResponse("destination_guide_url").asString().empty()
|
|
)
|
|
{
|
|
gMenuHolder->childSetVisible("Avatar Picker", false);
|
|
}
|
|
|
|
if (!LLLoginInstance::getInstance()->hasResponse("avatar_picker_url")
|
|
||LLLoginInstance::getInstance()->getResponse("avatar_picker_url").asString().empty()
|
|
)
|
|
{
|
|
gMenuHolder->childSetVisible("Destinations", false);
|
|
}
|
|
}
|
|
#endif // OPENSIM // <FS:AW optional opensim support>
|
|
// </FS:AW opensim destinations and avatar picker>
|
|
|
|
return true;
|
|
}
|
|
// </AW: OpenSim>
|
|
|
|
class LLToggleHelp : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLFloater* help_browser = (LLFloaterReg::findInstance("help_browser"));
|
|
if (help_browser && help_browser->isInVisibleChain())
|
|
{
|
|
help_browser->closeFloater();
|
|
}
|
|
else
|
|
{
|
|
std::string help_topic = userdata.asString();
|
|
LLViewerHelp* vhelp = LLViewerHelp::getInstance();
|
|
vhelp->showTopic(help_topic);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToggleSpeak : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVoiceClient::getInstance()->toggleUserPTTState();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
bool callback_show_url(const LLSD& notification, const LLSD& response)
|
|
{
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
if (0 == option)
|
|
{
|
|
LLWeb::loadURL(notification["payload"]["url"].asString());
|
|
}
|
|
return false;
|
|
}
|
|
|
|
class LLPromptShowURL : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string param = userdata.asString();
|
|
std::string::size_type offset = param.find(",");
|
|
if (offset != param.npos)
|
|
{
|
|
std::string alert = param.substr(0, offset);
|
|
std::string url = param.substr(offset+1);
|
|
|
|
if (LLWeb::useExternalBrowser(url))
|
|
{
|
|
// <FS:Ansariel> FS-1951: LLWeb::loadURL() will spawn the WebLaunchExternalTarget
|
|
// confirmation if opening with an external browser
|
|
//LLSD payload;
|
|
//payload["url"] = url;
|
|
//LLNotificationsUtil::add(alert, LLSD(), payload, callback_show_url);
|
|
if (alert == "WebLaunchExternalTarget")
|
|
{
|
|
LLWeb::loadURL(url);
|
|
}
|
|
else
|
|
{
|
|
LLSD payload;
|
|
payload["url"] = url;
|
|
LLNotificationsUtil::add(alert, LLSD(), payload, callback_show_url);
|
|
}
|
|
// </FS:Ansariel>
|
|
}
|
|
else
|
|
{
|
|
LLWeb::loadURL(url);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LL_INFOS() << "PromptShowURL invalid parameters! Expecting \"ALERT,URL\"." << LL_ENDL;
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
bool callback_show_file(const LLSD& notification, const LLSD& response)
|
|
{
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
if (0 == option)
|
|
{
|
|
LLWeb::loadURL(notification["payload"]["url"]);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
class LLPromptShowFile : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string param = userdata.asString();
|
|
std::string::size_type offset = param.find(",");
|
|
if (offset != param.npos)
|
|
{
|
|
std::string alert = param.substr(0, offset);
|
|
std::string file = param.substr(offset+1);
|
|
|
|
LLSD payload;
|
|
payload["url"] = file;
|
|
LLNotificationsUtil::add(alert, LLSD(), payload, callback_show_file);
|
|
}
|
|
else
|
|
{
|
|
LL_INFOS() << "PromptShowFile invalid parameters! Expecting \"ALERT,FILE\"." << LL_ENDL;
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLShowAgentProfile : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLUUID agent_id;
|
|
if (userdata.asString() == "agent")
|
|
{
|
|
agent_id = gAgent.getID();
|
|
}
|
|
else if (userdata.asString() == "hit object")
|
|
{
|
|
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (objectp)
|
|
{
|
|
agent_id = objectp->getID();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
agent_id = userdata.asUUID();
|
|
}
|
|
|
|
LLVOAvatar* avatar = find_avatar_from_object(agent_id);
|
|
// if (avatar)
|
|
// [RLVa:KB] - Checked: RLVa-1.2.0
|
|
if ( (avatar) && ((RlvActions::canShowName(RlvActions::SNC_DEFAULT, agent_id)) || (gAgent.getID() == agent_id)) )
|
|
// [/RLVa:KB]
|
|
{
|
|
LLAvatarActions::showProfile(avatar->getID());
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLShowAgentProfilePicks : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLAvatarActions::showPicks(gAgent.getID());
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToggleAgentProfile : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLUUID agent_id;
|
|
if (userdata.asString() == "agent")
|
|
{
|
|
agent_id = gAgent.getID();
|
|
}
|
|
else if (userdata.asString() == "hit object")
|
|
{
|
|
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (objectp)
|
|
{
|
|
agent_id = objectp->getID();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
agent_id = userdata.asUUID();
|
|
}
|
|
|
|
LLVOAvatar* avatar = find_avatar_from_object(agent_id);
|
|
if (avatar)
|
|
{
|
|
if (!LLAvatarActions::profileVisible(avatar->getID()))
|
|
{
|
|
LLAvatarActions::showProfile(avatar->getID());
|
|
}
|
|
else
|
|
{
|
|
LLAvatarActions::hideProfile(avatar->getID());
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLLandEdit : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (gAgentCamera.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") )
|
|
{
|
|
// zoom in if we're looking at the avatar
|
|
gAgentCamera.setFocusOnAvatar(false, ANIMATE);
|
|
gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
|
|
|
|
gAgentCamera.cameraOrbitOver( F_PI * 0.25f );
|
|
gViewerWindow->moveCursorToCenter();
|
|
}
|
|
else if ( gSavedSettings.getBOOL("EditCameraMovement") )
|
|
{
|
|
gAgentCamera.setFocusGlobal(LLToolPie::getInstance()->getPick());
|
|
gViewerWindow->moveCursorToCenter();
|
|
}
|
|
|
|
|
|
LLViewerParcelMgr::getInstance()->selectParcelAt( LLToolPie::getInstance()->getPick().mPosGlobal );
|
|
|
|
LLFloaterReg::showInstance("build");
|
|
|
|
// Switch to land edit toolset
|
|
LLToolMgr::getInstance()->getCurrentToolset()->selectTool( LLToolSelectLand::getInstance() );
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLMuteParticle : public view_listener_t
|
|
{
|
|
// <FS:Ansariel> Blocklist sometimes shows "(waiting)" as avatar name when blocking particle owners
|
|
void onAvatarNameCache(const LLUUID& av_id, const LLAvatarName& av_name)
|
|
{
|
|
LLMute mute(av_id, av_name.getUserName(), LLMute::AGENT);
|
|
if (LLMuteList::getInstance()->isMuted(mute.mID))
|
|
{
|
|
LLMuteList::getInstance()->remove(mute);
|
|
}
|
|
else
|
|
{
|
|
LLMuteList::getInstance()->add(mute);
|
|
LLPanelBlockedList::showPanelAndSelect(mute.mID);
|
|
}
|
|
}
|
|
// </FS:Ansariel>
|
|
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLUUID id = LLToolPie::getInstance()->getPick().mParticleOwnerID;
|
|
|
|
if (id.notNull())
|
|
{
|
|
// <FS:Ansariel> Blocklist sometimes shows "(waiting)" as avatar name when blocking particle owners
|
|
//LLAvatarName av_name;
|
|
//LLAvatarNameCache::get(id, &av_name);
|
|
|
|
//LLMute mute(id, av_name.getUserName(), LLMute::AGENT);
|
|
//if (LLMuteList::getInstance()->isMuted(mute.mID))
|
|
//{
|
|
// LLMuteList::getInstance()->remove(mute);
|
|
//}
|
|
//else
|
|
//{
|
|
// LLMuteList::getInstance()->add(mute);
|
|
// LLPanelBlockedList::showPanelAndSelect(mute.mID);
|
|
//}
|
|
LLAvatarNameCache::get(id, boost::bind(&LLMuteParticle::onAvatarNameCache, this, _1, _2));
|
|
// </FS:Ansariel>
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLWorldEnableBuyLand : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLViewerParcelMgr::getInstance()->canAgentBuyParcel(
|
|
LLViewerParcelMgr::getInstance()->selectionEmpty()
|
|
? LLViewerParcelMgr::getInstance()->getAgentParcel()
|
|
: LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(),
|
|
false);
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
bool enable_buy_land()
|
|
{
|
|
return LLViewerParcelMgr::getInstance()->canAgentBuyParcel(
|
|
LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel(), false);
|
|
}
|
|
|
|
void handle_buy_land()
|
|
{
|
|
LLViewerParcelMgr* vpm = LLViewerParcelMgr::getInstance();
|
|
if (vpm->selectionEmpty())
|
|
{
|
|
vpm->selectParcelAt(gAgent.getPositionGlobal());
|
|
}
|
|
vpm->startBuyLand();
|
|
}
|
|
|
|
class LLObjectAttachToAvatar : public view_listener_t
|
|
{
|
|
public:
|
|
LLObjectAttachToAvatar(bool replace) : mReplace(replace) {}
|
|
static void setObjectSelection(LLObjectSelectionHandle selection) { sObjectSelection = selection; }
|
|
|
|
private:
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
setObjectSelection(LLSelectMgr::getInstance()->getSelection());
|
|
LLViewerObject* selectedObject = sObjectSelection->getFirstRootObject();
|
|
if (selectedObject)
|
|
{
|
|
S32 index = userdata.asInteger();
|
|
LLViewerJointAttachment* attachment_point = NULL;
|
|
if (index > 0)
|
|
attachment_point = get_if_there(gAgentAvatarp->mAttachmentPoints, index, (LLViewerJointAttachment*)NULL);
|
|
|
|
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f
|
|
// RELEASE-RLVa: [SL-2.2.0] If 'index != 0' then the object will be "add attached" [see LLSelectMgr::sendAttach()]
|
|
if ( (rlv_handler_t::isEnabled()) &&
|
|
( ((!index) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY))) || // Can't wear on default
|
|
((index) && ((RLV_WEAR_ADD & gRlvAttachmentLocks.canAttach(attachment_point)) == 0)) || // or non-attachable attachpt
|
|
(gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) ) // Attach on object == "Take"
|
|
{
|
|
setObjectSelection(NULL); // Clear the selection or it'll get stuck
|
|
return true;
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
confirmReplaceAttachment(0, attachment_point);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
static void onNearAttachObject(bool success, void *user_data);
|
|
void confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point);
|
|
class CallbackData : public LLSelectionCallbackData
|
|
{
|
|
public:
|
|
CallbackData(LLViewerJointAttachment* point, bool replace) : LLSelectionCallbackData(), mAttachmentPoint(point), mReplace(replace) {}
|
|
|
|
LLViewerJointAttachment* mAttachmentPoint;
|
|
bool mReplace;
|
|
};
|
|
|
|
protected:
|
|
static LLObjectSelectionHandle sObjectSelection;
|
|
bool mReplace;
|
|
};
|
|
|
|
LLObjectSelectionHandle LLObjectAttachToAvatar::sObjectSelection;
|
|
|
|
// static
|
|
void LLObjectAttachToAvatar::onNearAttachObject(bool success, void *user_data)
|
|
{
|
|
if (!user_data) return;
|
|
CallbackData* cb_data = static_cast<CallbackData*>(user_data);
|
|
|
|
if (success)
|
|
{
|
|
const LLViewerJointAttachment *attachment = cb_data->mAttachmentPoint;
|
|
|
|
U8 attachment_id = 0;
|
|
if (attachment)
|
|
{
|
|
for (LLVOAvatar::attachment_map_t::const_iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
|
|
iter != gAgentAvatarp->mAttachmentPoints.end(); ++iter)
|
|
{
|
|
if (iter->second == attachment)
|
|
{
|
|
attachment_id = iter->first;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// interpret 0 as "default location"
|
|
attachment_id = 0;
|
|
}
|
|
LLSelectMgr::getInstance()->sendAttach(cb_data->getSelection(), attachment_id, cb_data->mReplace);
|
|
}
|
|
LLObjectAttachToAvatar::setObjectSelection(nullptr);
|
|
|
|
delete cb_data;
|
|
}
|
|
|
|
// static
|
|
void LLObjectAttachToAvatar::confirmReplaceAttachment(S32 option, LLViewerJointAttachment* attachment_point)
|
|
{
|
|
if (option == 0/*YES*/)
|
|
{
|
|
LLViewerObject* selectedObject = LLSelectMgr::getInstance()->getSelection()->getFirstRootObject();
|
|
if (selectedObject)
|
|
{
|
|
const F32 MIN_STOP_DISTANCE = 1.f; // meters
|
|
const F32 ARM_LENGTH = 0.5f; // meters
|
|
const F32 SCALE_FUDGE = 1.5f;
|
|
|
|
F32 stop_distance = SCALE_FUDGE * selectedObject->getMaxScale() + ARM_LENGTH;
|
|
if (stop_distance < MIN_STOP_DISTANCE)
|
|
{
|
|
stop_distance = MIN_STOP_DISTANCE;
|
|
}
|
|
|
|
LLVector3 walkToSpot = selectedObject->getPositionAgent();
|
|
|
|
// make sure we stop in front of the object
|
|
LLVector3 delta = walkToSpot - gAgent.getPositionAgent();
|
|
delta.normVec();
|
|
delta = delta * 0.5f;
|
|
walkToSpot -= delta;
|
|
|
|
// The callback will be called even if avatar fails to get close enough to the object, so we won't get a memory leak.
|
|
CallbackData* user_data = new CallbackData(attachment_point, mReplace);
|
|
gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, onNearAttachObject, user_data, stop_distance);
|
|
gAgentCamera.clearFocusObject();
|
|
}
|
|
}
|
|
}
|
|
|
|
void callback_attachment_drop(const LLSD& notification, const LLSD& response)
|
|
{
|
|
// Ensure user confirmed the drop
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
if (option != 0) return;
|
|
|
|
// Called when the user clicked on an object attached to them
|
|
// and selected "Drop".
|
|
LLUUID object_id = notification["payload"]["object_id"].asUUID();
|
|
LLViewerObject *object = gObjectList.findObject(object_id);
|
|
|
|
if (!object)
|
|
{
|
|
LL_WARNS() << "handle_drop_attachment() - no object to drop" << LL_ENDL;
|
|
return;
|
|
}
|
|
|
|
LLViewerObject *parent = (LLViewerObject*)object->getParent();
|
|
while (parent)
|
|
{
|
|
if(parent->isAvatar())
|
|
{
|
|
break;
|
|
}
|
|
object = parent;
|
|
parent = (LLViewerObject*)parent->getParent();
|
|
}
|
|
|
|
if (!object)
|
|
{
|
|
LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL;
|
|
return;
|
|
}
|
|
|
|
if (object->isAvatar())
|
|
{
|
|
LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL;
|
|
return;
|
|
}
|
|
|
|
// reselect the object
|
|
LLSelectMgr::getInstance()->selectObjectAndFamily(object);
|
|
|
|
LLSelectMgr::getInstance()->sendDropAttachment();
|
|
|
|
return;
|
|
}
|
|
|
|
class LLAttachmentDrop : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-03-15 (RLVa-1.2.0e) | Modified: RLVa-1.0.5
|
|
if (rlv_handler_t::isEnabled())
|
|
{
|
|
if (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE))
|
|
{
|
|
// NOTE: copy/paste of the code in enable_detach()
|
|
LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection();
|
|
RlvSelectHasLockedAttach f;
|
|
if ( (hSelect->isAttachment()) && (hSelect->getFirstRootNode(&f, false) != NULL) )
|
|
return true;
|
|
}
|
|
if (gRlvHandler.hasBehaviour(RLV_BHVR_REZ))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
LLSD payload;
|
|
LLViewerObject *object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
|
|
if (object)
|
|
{
|
|
payload["object_id"] = object->getID();
|
|
}
|
|
else
|
|
{
|
|
LL_WARNS() << "Drop object not found" << LL_ENDL;
|
|
return true;
|
|
}
|
|
|
|
LLNotificationsUtil::add("AttachmentDrop", LLSD(), payload, &callback_attachment_drop);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// called from avatar pie menu
|
|
class LLAttachmentDetachFromPoint : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& user_data)
|
|
{
|
|
uuid_vec_t ids_to_remove;
|
|
const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, user_data.asInteger(), (LLViewerJointAttachment*)NULL);
|
|
// if (attachment->getNumObjects() > 0)
|
|
// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
|
|
if ( (attachment->getNumObjects() > 0) && ((!rlv_handler_t::isEnabled()) || (gRlvAttachmentLocks.canDetach(attachment))) )
|
|
// [/RLVa:KB]
|
|
{
|
|
for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator iter = attachment->mAttachedObjects.begin();
|
|
iter != attachment->mAttachedObjects.end();
|
|
iter++)
|
|
{
|
|
LLViewerObject *attached_object = iter->get();
|
|
// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
|
|
if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.isLockedAttachment(attached_object)) )
|
|
continue;
|
|
ids_to_remove.push_back(attached_object->getAttachmentItemID());
|
|
// [/RLVa:KB]
|
|
}
|
|
}
|
|
if (!ids_to_remove.empty())
|
|
{
|
|
LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
static bool onEnableAttachmentLabel(LLUICtrl* ctrl, const LLSD& data)
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f
|
|
// RELEASE-RLVa: [SL-2.2.0] When attaching to a specific point the object will be "add attached" [see LLSelectMgr::sendAttach()]
|
|
bool fRlvEnable = true;
|
|
// [/RLVa:KB]
|
|
std::string label;
|
|
LLMenuItemGL* menu = dynamic_cast<LLMenuItemGL*>(ctrl);
|
|
if (menu)
|
|
{
|
|
const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, data["index"].asInteger(), (LLViewerJointAttachment*)NULL);
|
|
if (attachment)
|
|
{
|
|
label = data["label"].asString();
|
|
for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator attachment_iter = attachment->mAttachedObjects.begin();
|
|
attachment_iter != attachment->mAttachedObjects.end();
|
|
++attachment_iter)
|
|
{
|
|
const LLViewerObject* attached_object = attachment_iter->get();
|
|
if (attached_object)
|
|
{
|
|
LLViewerInventoryItem* itemp = gInventory.getItem(attached_object->getAttachmentItemID());
|
|
// <FS:Ansariel> Hide bridge from attach to HUD menus
|
|
//if (itemp)
|
|
if (itemp && !(FSLSLBridge::instance().getBridge() && FSLSLBridge::instance().getBridge()->getUUID() == itemp->getUUID() && data["index"].asInteger() == FS_BRIDGE_POINT))
|
|
// </FS:Ansariel>
|
|
{
|
|
label += std::string(" (") + itemp->getName() + std::string(")");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f
|
|
if (rlv_handler_t::isEnabled())
|
|
fRlvEnable = (!gRlvAttachmentLocks.isLockedAttachmentPoint(attachment, RLV_LOCK_ADD));
|
|
// [/RLVa:KB]
|
|
|
|
menu->setLabel(label);
|
|
}
|
|
// return true;
|
|
// [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
|
|
return fRlvEnable;
|
|
// [/RLVa:KB]
|
|
}
|
|
|
|
class LLAttachmentDetach : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// Called when the user clicked on an object attached to them
|
|
// and selected "Detach".
|
|
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
|
|
LLViewerObject *object = selection->getPrimaryObject();
|
|
if (!object)
|
|
{
|
|
LL_WARNS() << "handle_detach() - no object to detach" << LL_ENDL;
|
|
return true;
|
|
}
|
|
|
|
struct f: public LLSelectedObjectFunctor
|
|
{
|
|
f() : mAvatarsInSelection(false) {}
|
|
virtual bool apply(LLViewerObject* objectp)
|
|
{
|
|
if (!objectp)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (objectp->isAvatar())
|
|
{
|
|
mAvatarsInSelection = true;
|
|
return false;
|
|
}
|
|
|
|
LLViewerObject* parent = (LLViewerObject*)objectp->getParent();
|
|
while (parent)
|
|
{
|
|
if(parent->isAvatar())
|
|
{
|
|
break;
|
|
}
|
|
objectp = parent;
|
|
parent = (LLViewerObject*)parent->getParent();
|
|
}
|
|
|
|
// [RLVa:KB] - Checked: 2010-03-15 (RLVa-1.2.0a) | Modified: RLVa-1.0.5
|
|
// NOTE: copy/paste of the code in enable_detach()
|
|
if ((rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) &&
|
|
gRlvAttachmentLocks.isLockedAttachment(objectp->getRootEdit()))
|
|
{
|
|
return false;
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
// std::set to avoid dupplicate 'roots' from linksets
|
|
mRemoveSet.insert(objectp->getAttachmentItemID());
|
|
|
|
return true;
|
|
}
|
|
bool mAvatarsInSelection;
|
|
uuid_set_t mRemoveSet;
|
|
} func;
|
|
// Probbly can run applyToRootObjects instead,
|
|
// but previous version of this code worked for any selected object
|
|
selection->applyToObjects(&func);
|
|
|
|
if (func.mAvatarsInSelection)
|
|
{
|
|
// Not possible under normal circumstances
|
|
// Either avatar selection is ON or has to do with animeshes
|
|
// Better stop this than mess something
|
|
LL_WARNS() << "Trying to detach avatar from avatar." << LL_ENDL;
|
|
return true;
|
|
}
|
|
|
|
if (func.mRemoveSet.empty())
|
|
{
|
|
LL_WARNS() << "handle_detach() - no valid attachments in selection to detach" << LL_ENDL;
|
|
return true;
|
|
}
|
|
|
|
uuid_vec_t detach_list(func.mRemoveSet.begin(), func.mRemoveSet.end());
|
|
LLAppearanceMgr::instance().removeItemsFromAvatar(detach_list);
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
//Adding an observer for a Jira 2422 and needs to be a fetch observer
|
|
//for Jira 3119
|
|
class LLWornItemFetchedObserver : public LLInventoryFetchItemsObserver
|
|
{
|
|
public:
|
|
LLWornItemFetchedObserver(const LLUUID& worn_item_id) :
|
|
LLInventoryFetchItemsObserver(worn_item_id)
|
|
{}
|
|
virtual ~LLWornItemFetchedObserver() {}
|
|
|
|
protected:
|
|
virtual void done()
|
|
{
|
|
gMenuAttachmentSelf->buildDrawLabels();
|
|
gInventory.removeObserver(this);
|
|
delete this;
|
|
}
|
|
};
|
|
|
|
// You can only drop items on parcels where you can build.
|
|
class LLAttachmentEnableDrop : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool can_build = gAgent.isGodlike() || (LLViewerParcelMgr::getInstance()->allowAgentBuild());
|
|
|
|
//Add an inventory observer to only allow dropping the newly attached item
|
|
//once it exists in your inventory. Look at Jira 2422.
|
|
//-jwolk
|
|
|
|
// A bug occurs when you wear/drop an item before it actively is added to your inventory
|
|
// if this is the case (you're on a slow sim, etc.) a copy of the object,
|
|
// well, a newly created object with the same properties, is placed
|
|
// in your inventory. Therefore, we disable the drop option until the
|
|
// item is in your inventory
|
|
|
|
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
LLViewerJointAttachment* attachment = NULL;
|
|
LLInventoryItem* item = NULL;
|
|
|
|
// Do not enable drop if all faces of object are not enabled
|
|
if (object && LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES ))
|
|
{
|
|
S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getAttachmentState());
|
|
attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, attachmentID, (LLViewerJointAttachment*)NULL);
|
|
|
|
if (attachment)
|
|
{
|
|
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
|
|
attachment_iter != attachment->mAttachedObjects.end();
|
|
++attachment_iter)
|
|
{
|
|
// make sure item is in your inventory (it could be a delayed attach message being sent from the sim)
|
|
// so check to see if the item is in the inventory already
|
|
item = gInventory.getItem(attachment_iter->get()->getAttachmentItemID());
|
|
if (!item)
|
|
{
|
|
// Item does not exist, make an observer to enable the pie menu
|
|
// when the item finishes fetching worst case scenario
|
|
// if a fetch is already out there (being sent from a slow sim)
|
|
// we refetch and there are 2 fetches
|
|
LLWornItemFetchedObserver* worn_item_fetched = new LLWornItemFetchedObserver((*attachment_iter)->getAttachmentItemID());
|
|
worn_item_fetched->startFetch();
|
|
gInventory.addObserver(worn_item_fetched);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
//now check to make sure that the item is actually in the inventory before we enable dropping it
|
|
// bool new_value = enable_detach() && can_build && item;
|
|
// [RLVa:KB] - Checked: 2010-03-24 (RLVa-1.0.0b) | Modified: RLVa-1.0.0b
|
|
bool new_value = enable_detach() && can_build && item && (!gRlvHandler.hasBehaviour(RLV_BHVR_REZ));
|
|
// [/RLVa:KB]
|
|
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
bool enable_detach(const LLSD&)
|
|
{
|
|
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
|
|
// Only enable detach if all faces of object are selected
|
|
if (!object ||
|
|
!object->isAttachment() ||
|
|
!LLSelectMgr::getInstance()->getSelection()->contains(object,SELECT_ALL_TES ))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Find the avatar who owns this attachment
|
|
LLViewerObject* avatar = object;
|
|
while (avatar)
|
|
{
|
|
// ...if it's you, good to detach
|
|
if (avatar->getID() == gAgent.getID())
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-03-15 (RLVa-1.2.0a) | Modified: RLVa-1.0.5
|
|
// NOTE: this code is reused as-is in LLAttachmentDetach::handleEvent() and LLAttachmentDrop::handleEvent()
|
|
// so any changes here should be reflected there as well
|
|
|
|
// RELEASE-RLVa: [SL-2.2.0] LLSelectMgr::sendDetach() and LLSelectMgr::sendDropAttachment() call sendListToRegions with
|
|
// SEND_ONLY_ROOTS so we only need to examine the roots which saves us time
|
|
if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) )
|
|
{
|
|
LLObjectSelectionHandle hSelect = LLSelectMgr::getInstance()->getSelection();
|
|
RlvSelectHasLockedAttach f;
|
|
if ( (hSelect->isAttachment()) && (hSelect->getFirstRootNode(&f, false) != NULL) )
|
|
return false;
|
|
}
|
|
// [/RLVa:KB]
|
|
return true;
|
|
}
|
|
|
|
avatar = (LLViewerObject*)avatar->getParent();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
class LLAttachmentEnableDetach : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = enable_detach();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
// Used to tell if the selected object can be attached to your avatar.
|
|
//bool object_selected_and_point_valid()
|
|
// [RLVa:KB] - Checked: 2010-03-16 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
|
|
bool object_selected_and_point_valid(const LLSD& sdParam)
|
|
// [/RLVa:KB]
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f
|
|
if (rlv_handler_t::isEnabled())
|
|
{
|
|
if (!isAgentAvatarValid())
|
|
return false;
|
|
|
|
// RELEASE-RLVa: [SL-2.2.0] Look at the caller graph for this function on every new release
|
|
// - object_is_wearable() => dead code [sdParam == 0 => default attach point => OK!]
|
|
// - enabler set up in LLVOAvatarSelf::buildMenus() => Rezzed prim / Put On / "Attach To" [sdParam == idxAttachPt]
|
|
// - "Object.EnableWear" enable => Rezzed prim / Put On / "Wear" or "Add" [sdParam blank]
|
|
// RELEASE-RLVa: [SL-2.2.0] If 'idxAttachPt != 0' then the object will be "add attached" [see LLSelectMgr::sendAttach()]
|
|
const LLViewerJointAttachment* pAttachPt =
|
|
get_if_there(gAgentAvatarp->mAttachmentPoints, sdParam.asInteger(), (LLViewerJointAttachment*)NULL);
|
|
if ( ((!pAttachPt) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY))) || // Can't wear on default attach point
|
|
((pAttachPt) && ((RLV_WEAR_ADD & gRlvAttachmentLocks.canAttach(pAttachPt)) == 0)) || // or non-attachable attach point
|
|
(gRlvHandler.hasBehaviour(RLV_BHVR_REZ)) ) // Attach on object == "Take"
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
|
|
for (LLObjectSelection::root_iterator iter = selection->root_begin();
|
|
iter != selection->root_end(); iter++)
|
|
{
|
|
LLSelectNode* node = *iter;
|
|
LLViewerObject* object = node->getObject();
|
|
LLViewerObject::const_child_list_t& child_list = object->getChildren();
|
|
for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
|
|
iter != child_list.end(); iter++)
|
|
{
|
|
LLViewerObject* child = *iter;
|
|
if (child->isAvatar())
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
|
|
return (selection->getRootObjectCount() == 1) &&
|
|
(selection->getFirstRootObject()->getPCode() == LL_PCODE_VOLUME) &&
|
|
selection->getFirstRootObject()->permYouOwner() &&
|
|
selection->getFirstRootObject()->flagObjectMove() &&
|
|
!selection->getFirstRootObject()->flagObjectPermanent() &&
|
|
!((LLViewerObject*)selection->getFirstRootObject()->getRoot())->isAvatar() &&
|
|
(selection->getFirstRootObject()->getNVPair("AssetContainer") == NULL);
|
|
}
|
|
|
|
|
|
bool object_is_wearable()
|
|
{
|
|
if (!isAgentAvatarValid())
|
|
{
|
|
return false;
|
|
}
|
|
// if (!object_selected_and_point_valid())
|
|
// [RLVa:KB] - Checked: 2010-03-16 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
|
|
if (!object_selected_and_point_valid(LLSD(0)))
|
|
// [/RLVa:KB]
|
|
{
|
|
return false;
|
|
}
|
|
if (sitting_on_selection())
|
|
{
|
|
return false;
|
|
}
|
|
return gAgentAvatarp->canAttachMoreObjects();
|
|
}
|
|
|
|
class LLAttachmentPointFilled : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& user_data)
|
|
{
|
|
bool enable = false;
|
|
LLVOAvatar::attachment_map_t::iterator found_it = gAgentAvatarp->mAttachmentPoints.find(user_data.asInteger());
|
|
if (found_it != gAgentAvatarp->mAttachmentPoints.end())
|
|
{
|
|
// enable = found_it->second->getNumObjects() > 0;
|
|
// [RLVa:KB] - Checked: 2010-03-04 (RLVa-1.2.0a) | Added: RLVa-1.2.0a
|
|
// Enable the option if there is at least one attachment on this attachment point that can be detached
|
|
enable = (found_it->second->getNumObjects() > 0) &&
|
|
((!rlv_handler_t::isEnabled()) || (gRlvAttachmentLocks.canDetach(found_it->second)));
|
|
// [/RLVa:KB]
|
|
}
|
|
return enable;
|
|
}
|
|
};
|
|
|
|
class LLAvatarSendIM : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
|
// if(avatar)
|
|
// [RLVa:KB] - Checked: RLVa-1.2.0
|
|
if ( (avatar) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) )
|
|
// [/RLVa:KB]
|
|
{
|
|
LLAvatarActions::startIM(avatar->getID());
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAvatarCall : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
|
|
// if(avatar)
|
|
// [RLVa:KB] - Checked: RLVa-1.2.0
|
|
if ( (avatar) && (RlvActions::canShowName(RlvActions::SNC_DEFAULT, avatar->getID())) )
|
|
// [/RLVa:KB]
|
|
{
|
|
LLAvatarActions::startCall(avatar->getID());
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// [RLVa:KB] - Checked: RLVa-1.2.1
|
|
bool enable_avatar_call()
|
|
{
|
|
if (RlvActions::isRlvEnabled())
|
|
{
|
|
const LLVOAvatar* pAvatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
|
|
if ((!pAvatar) || (!RlvActions::canShowName(RlvActions::SNC_DEFAULT, pAvatar->getID())))
|
|
return false;
|
|
}
|
|
return LLAvatarActions::canCall();
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
namespace
|
|
{
|
|
struct QueueObjects : public LLSelectedNodeFunctor
|
|
{
|
|
bool scripted;
|
|
bool modifiable;
|
|
LLFloaterScriptQueue* mQueue;
|
|
QueueObjects(LLFloaterScriptQueue* q) : mQueue(q), scripted(false), modifiable(false) {}
|
|
virtual bool apply(LLSelectNode* node)
|
|
{
|
|
LLViewerObject* obj = node->getObject();
|
|
if (!obj)
|
|
{
|
|
return true;
|
|
}
|
|
scripted = obj->flagScripted();
|
|
modifiable = obj->permModify();
|
|
|
|
if( scripted && modifiable )
|
|
{
|
|
mQueue->addObject(obj->getID(), node->mName);
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true; // fail: stop applying
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
bool queue_actions(LLFloaterScriptQueue* q, const std::string& msg)
|
|
{
|
|
QueueObjects func(q);
|
|
LLSelectMgr *mgr = LLSelectMgr::getInstance();
|
|
LLObjectSelectionHandle selectHandle = mgr->getSelection();
|
|
bool fail = selectHandle->applyToNodes(&func);
|
|
if(fail)
|
|
{
|
|
if ( !func.scripted )
|
|
{
|
|
std::string noscriptmsg = std::string("Cannot") + msg + "SelectObjectsNoScripts";
|
|
LLNotificationsUtil::add(noscriptmsg);
|
|
}
|
|
else if ( !func.modifiable )
|
|
{
|
|
std::string nomodmsg = std::string("Cannot") + msg + "SelectObjectsNoPermission";
|
|
LLNotificationsUtil::add(nomodmsg);
|
|
}
|
|
else
|
|
{
|
|
LL_ERRS() << "Bad logic." << LL_ENDL;
|
|
}
|
|
q->closeFloater();
|
|
}
|
|
else
|
|
{
|
|
if (!q->start())
|
|
{
|
|
LL_WARNS() << "Unexpected script compile failure." << LL_ENDL;
|
|
}
|
|
}
|
|
return !fail;
|
|
}
|
|
|
|
class LLToolsSelectedScriptAction : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// <FS> Script reset in edit floater
|
|
//std::string action = userdata.asString();
|
|
//bool mono = false;
|
|
//std::string msg, name;
|
|
//std::string title;
|
|
//if (action == "compile mono")
|
|
//{
|
|
// name = "compile_queue";
|
|
// mono = true;
|
|
// msg = "Recompile";
|
|
// title = LLTrans::getString("CompileQueueTitle");
|
|
//}
|
|
//if (action == "compile lsl")
|
|
//{
|
|
// name = "compile_queue";
|
|
// msg = "Recompile";
|
|
// title = LLTrans::getString("CompileQueueTitle");
|
|
//}
|
|
//else if (action == "reset")
|
|
//{
|
|
// name = "reset_queue";
|
|
// msg = "Reset";
|
|
// title = LLTrans::getString("ResetQueueTitle");
|
|
//}
|
|
//else if (action == "start")
|
|
//{
|
|
// name = "start_queue";
|
|
// msg = "SetRunning";
|
|
// title = LLTrans::getString("RunQueueTitle");
|
|
//}
|
|
//else if (action == "stop")
|
|
//{
|
|
// name = "stop_queue";
|
|
// msg = "SetRunningNot";
|
|
// title = LLTrans::getString("NotRunQueueTitle");
|
|
//}
|
|
//LLUUID id; id.generate();
|
|
|
|
//LLFloaterScriptQueue* queue = LLFloaterReg::getTypedInstance<LLFloaterScriptQueue>(name, LLSD(id));
|
|
//if (queue)
|
|
//{
|
|
// queue->setMono(mono);
|
|
// if (queue_actions(queue, msg))
|
|
// {
|
|
// queue->setTitle(title);
|
|
// }
|
|
//}
|
|
//else
|
|
//{
|
|
// LL_WARNS() << "Failed to generate LLFloaterScriptQueue with action: " << action << LL_ENDL;
|
|
//}
|
|
handle_selected_script_action(userdata.asString());
|
|
// </FS>
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// <FS> Script reset in edit floater
|
|
void handle_selected_script_action(const std::string& action)
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-04-19 (RLVa-1.2.0f) | Modified: RLVa-1.0.5a
|
|
// We'll allow resetting the scripts of objects on a non-attachable attach point since they wouldn't be able to circumvent anything
|
|
if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE)) )
|
|
{
|
|
LLObjectSelectionHandle hSel = LLSelectMgr::getInstance()->getSelection();
|
|
RlvSelectHasLockedAttach f;
|
|
if ( (hSel->isAttachment()) && (hSel->getFirstNode(&f) != NULL) )
|
|
return;
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
bool mono = false;
|
|
std::string msg, name;
|
|
std::string title;
|
|
if (action == "compile mono")
|
|
{
|
|
name = "compile_queue";
|
|
mono = true;
|
|
msg = "Recompile";
|
|
title = LLTrans::getString("CompileQueueTitle");
|
|
}
|
|
if (action == "compile lsl")
|
|
{
|
|
name = "compile_queue";
|
|
msg = "Recompile";
|
|
title = LLTrans::getString("CompileQueueTitle");
|
|
}
|
|
else if (action == "reset")
|
|
{
|
|
name = "reset_queue";
|
|
msg = "Reset";
|
|
title = LLTrans::getString("ResetQueueTitle");
|
|
}
|
|
else if (action == "start")
|
|
{
|
|
name = "start_queue";
|
|
msg = "SetRunning";
|
|
title = LLTrans::getString("RunQueueTitle");
|
|
}
|
|
else if (action == "stop")
|
|
{
|
|
name = "stop_queue";
|
|
msg = "SetRunningNot";
|
|
title = LLTrans::getString("NotRunQueueTitle");
|
|
}
|
|
// <FS> Delete scripts
|
|
else if (action == "delete")
|
|
{
|
|
name = "delete_queue";
|
|
msg = "delete";
|
|
title = LLTrans::getString("DeleteQueueTitle");
|
|
}
|
|
// </FS> Delete scripts
|
|
LLUUID id; id.generate();
|
|
|
|
LLFloaterScriptQueue* queue = LLFloaterReg::getTypedInstance<LLFloaterScriptQueue>(name, LLSD(id));
|
|
if (queue)
|
|
{
|
|
queue->setMono(mono);
|
|
if (queue_actions(queue, msg))
|
|
{
|
|
queue->setTitle(title);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LL_WARNS() << "Failed to generate LLFloaterScriptQueue with action: " << action << LL_ENDL;
|
|
}
|
|
}
|
|
// </FS>
|
|
|
|
void handle_selected_texture_info()
|
|
{
|
|
for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin();
|
|
iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++)
|
|
{
|
|
LLSelectNode* node = *iter;
|
|
|
|
std::string msg;
|
|
msg.assign("Texture info for: ");
|
|
msg.append(node->mName);
|
|
|
|
U8 te_count = node->getObject()->getNumTEs();
|
|
// map from texture ID to list of faces using it
|
|
typedef std::map< LLUUID, std::vector<U8> > map_t;
|
|
map_t faces_per_texture;
|
|
for (U8 i = 0; i < te_count; i++)
|
|
{
|
|
if (!node->isTESelected(i)) continue;
|
|
|
|
LLViewerTexture* img = node->getObject()->getTEImage(i);
|
|
LLUUID image_id = img->getID();
|
|
faces_per_texture[image_id].push_back(i);
|
|
}
|
|
// Per-texture, dump which faces are using it.
|
|
map_t::iterator it;
|
|
for (it = faces_per_texture.begin(); it != faces_per_texture.end(); ++it)
|
|
{
|
|
U8 te = it->second[0];
|
|
LLViewerTexture* img = node->getObject()->getTEImage(te);
|
|
S32 height = img->getHeight();
|
|
S32 width = img->getWidth();
|
|
S32 components = img->getComponents();
|
|
msg.append(llformat("\n%dx%d %s on face ",
|
|
width,
|
|
height,
|
|
(components == 4 ? "alpha" : "opaque")));
|
|
for (U8 i = 0; i < it->second.size(); ++i)
|
|
{
|
|
msg.append( llformat("%d ", (S32)(it->second[i])));
|
|
}
|
|
}
|
|
// <FS:Ansariel> Report texture info to local chat instead of toasts
|
|
//LLSD args;
|
|
//args["MESSAGE"] = msg;
|
|
//LLNotificationsUtil::add("SystemMessage", args);
|
|
FSCommon::report_to_nearby_chat(msg);
|
|
// </FS:Ansariel>
|
|
}
|
|
}
|
|
|
|
void handle_selected_material_info()
|
|
{
|
|
for (LLObjectSelection::valid_iterator iter = LLSelectMgr::getInstance()->getSelection()->valid_begin();
|
|
iter != LLSelectMgr::getInstance()->getSelection()->valid_end(); iter++)
|
|
{
|
|
LLSelectNode* node = *iter;
|
|
|
|
std::string msg;
|
|
msg.assign("Material info for: \n");
|
|
msg.append(node->mName);
|
|
|
|
U8 te_count = node->getObject()->getNumTEs();
|
|
// map from material ID to list of faces using it
|
|
typedef std::map<LLMaterialID, std::vector<U8> > map_t;
|
|
map_t faces_per_material;
|
|
for (U8 i = 0; i < te_count; i++)
|
|
{
|
|
if (!node->isTESelected(i)) continue;
|
|
|
|
const LLMaterialID& material_id = node->getObject()->getTEref(i).getMaterialID();
|
|
faces_per_material[material_id].push_back(i);
|
|
}
|
|
// Per-material, dump which faces are using it.
|
|
map_t::iterator it;
|
|
for (it = faces_per_material.begin(); it != faces_per_material.end(); ++it)
|
|
{
|
|
const LLMaterialID& material_id = it->first;
|
|
msg += llformat("%s on face ", material_id.asString().c_str());
|
|
for (U8 i = 0; i < it->second.size(); ++i)
|
|
{
|
|
msg.append( llformat("%d ", (S32)(it->second[i])));
|
|
}
|
|
msg.append("\n");
|
|
}
|
|
|
|
LLSD args;
|
|
args["MESSAGE"] = msg;
|
|
LLNotificationsUtil::add("SystemMessage", args);
|
|
}
|
|
}
|
|
|
|
void handle_test_male()
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0c) | Modified: RLVa-1.2.0a
|
|
// TODO-RLVa: [RLVa-1.2.1] Is there any reason to still block this?
|
|
if ( (rlv_handler_t::isEnabled()) &&
|
|
((gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) || (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY))) )
|
|
{
|
|
return;
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
LLAppearanceMgr::instance().wearOutfitByName("Male Shape & Outfit");
|
|
//gGestureList.requestResetFromServer( true );
|
|
}
|
|
|
|
void handle_test_female()
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-03-19 (RLVa-1.2.0c) | Modified: RLVa-1.2.0a
|
|
// TODO-RLVa: [RLVa-1.2.1] Is there any reason to still block this?
|
|
if ( (rlv_handler_t::isEnabled()) &&
|
|
((gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_ANY)) || (gRlvWearableLocks.hasLockedWearableType(RLV_LOCK_ANY))) )
|
|
{
|
|
return;
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
LLAppearanceMgr::instance().wearOutfitByName("Female Shape & Outfit");
|
|
//gGestureList.requestResetFromServer( false );
|
|
}
|
|
|
|
void handle_dump_attachments()
|
|
{
|
|
if (!isAgentAvatarValid())
|
|
return;
|
|
|
|
for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin();
|
|
iter != gAgentAvatarp->mAttachmentPoints.end(); )
|
|
{
|
|
LLVOAvatar::attachment_map_t::iterator curiter = iter++;
|
|
LLViewerJointAttachment* attachment = curiter->second;
|
|
S32 key = curiter->first;
|
|
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
|
|
attachment_iter != attachment->mAttachedObjects.end();
|
|
++attachment_iter)
|
|
{
|
|
LLViewerObject *attached_object = attachment_iter->get();
|
|
bool visible = (attached_object != NULL &&
|
|
attached_object->mDrawable.notNull() &&
|
|
!attached_object->mDrawable->isRenderType(0));
|
|
LLVector3 pos;
|
|
if (visible) pos = attached_object->mDrawable->getPosition();
|
|
LL_INFOS() << "ATTACHMENT " << key << ": item_id=" << attached_object->getAttachmentItemID()
|
|
<< (attached_object ? " present " : " absent ")
|
|
<< (visible ? "visible " : "invisible ")
|
|
<< " at " << pos
|
|
<< " and " << (visible ? attached_object->getPosition() : LLVector3::zero)
|
|
<< LL_ENDL;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// these are used in the gl menus to set control values, generically.
|
|
class LLToggleControl : public view_listener_t
|
|
{
|
|
protected:
|
|
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string control_name = userdata.asString();
|
|
bool checked = gSavedSettings.getBOOL( control_name );
|
|
gSavedSettings.setBOOL( control_name, !checked );
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLCheckControl : public view_listener_t
|
|
{
|
|
bool handleEvent( const LLSD& userdata)
|
|
{
|
|
std::string callback_data = userdata.asString();
|
|
bool new_value = gSavedSettings.getBOOL(callback_data);
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
// <FS:Ansariel> Control enhancements
|
|
class LLTogglePerAccountControl : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string control_name = userdata.asString();
|
|
bool checked = gSavedPerAccountSettings.getBOOL( control_name );
|
|
gSavedPerAccountSettings.setBOOL( control_name, !checked );
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLCheckPerAccountControl : public view_listener_t
|
|
{
|
|
bool handleEvent( const LLSD& userdata)
|
|
{
|
|
std::string callback_data = userdata.asString();
|
|
bool new_value = gSavedPerAccountSettings.getBOOL(callback_data);
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class FSResetControl : public view_listener_t
|
|
{
|
|
bool handleEvent( const LLSD& userdata)
|
|
{
|
|
std::string callback_data = userdata.asString();
|
|
gSavedSettings.getControl(callback_data)->resetToDefault(true);
|
|
return true;
|
|
}
|
|
};
|
|
class FSResetPerAccountControl : public view_listener_t
|
|
{
|
|
bool handleEvent( const LLSD& userdata)
|
|
{
|
|
std::string callback_data = userdata.asString();
|
|
gSavedPerAccountSettings.getControl(callback_data)->resetToDefault(true);
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:Ansariel> Control enhancements
|
|
|
|
// <FS:Ansariel> Reset Mesh LOD; Forcing highest LOD on each mesh briefly should fix
|
|
// broken meshes bursted into triangles
|
|
static void reset_mesh_lod(LLVOAvatar* avatar)
|
|
{
|
|
for (LLVOAvatar::attachment_map_t::iterator it = avatar->mAttachmentPoints.begin(); it != avatar->mAttachmentPoints.end(); it++)
|
|
{
|
|
LLViewerJointAttachment::attachedobjs_vec_t& att_objects = (*it).second->mAttachedObjects;
|
|
|
|
for (LLViewerJointAttachment::attachedobjs_vec_t::iterator at_it = att_objects.begin(); at_it != att_objects.end(); at_it++)
|
|
{
|
|
LLViewerObject* objectp = *at_it;
|
|
if (objectp)
|
|
{
|
|
if (objectp->getPCode() == LL_PCODE_VOLUME)
|
|
{
|
|
LLVOVolume* vol = (LLVOVolume*)objectp;
|
|
if (vol && vol->isMesh())
|
|
{
|
|
vol->forceLOD(LLModel::LOD_HIGH);
|
|
}
|
|
}
|
|
|
|
LLViewerObject::const_child_list_t& children = objectp->getChildren();
|
|
for (LLViewerObject::const_child_list_t::const_iterator cit = children.begin(); cit != children.end(); cit++)
|
|
{
|
|
LLViewerObject* child_objectp = *cit;
|
|
if (!child_objectp || (child_objectp->getPCode() != LL_PCODE_VOLUME))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
LLVOVolume* child_vol = (LLVOVolume*)child_objectp;
|
|
if (child_vol && child_vol->isMesh())
|
|
{
|
|
child_vol->forceLOD(LLModel::LOD_HIGH);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class FSResetMeshLOD : public view_listener_t
|
|
{
|
|
bool handleEvent( const LLSD& userdata)
|
|
{
|
|
LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
|
|
if (avatar)
|
|
{
|
|
reset_mesh_lod(avatar);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:Ansariel>
|
|
|
|
// not so generic
|
|
|
|
class LLAdvancedCheckRenderShadowOption: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string control_name = userdata.asString();
|
|
S32 current_shadow_level = gSavedSettings.getS32(control_name);
|
|
if (current_shadow_level == 0) // is off
|
|
{
|
|
return false;
|
|
}
|
|
else // is on
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
};
|
|
|
|
class LLAdvancedClickRenderShadowOption: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string control_name = userdata.asString();
|
|
S32 current_shadow_level = gSavedSettings.getS32(control_name);
|
|
if (current_shadow_level == 0) // upgrade to level 2
|
|
{
|
|
gSavedSettings.setS32(control_name, 2);
|
|
}
|
|
else // downgrade to level 0
|
|
{
|
|
gSavedSettings.setS32(control_name, 0);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedClickRenderProfile: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gShaderProfileFrame = true;
|
|
return true;
|
|
}
|
|
};
|
|
|
|
F32 gpu_benchmark();
|
|
|
|
class LLAdvancedClickRenderBenchmark: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gpu_benchmark();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
void hdri_preview();
|
|
|
|
class LLAdvancedClickHDRIPreview: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// open personal lighting floater when previewing an HDRI (keeps HDRI from implicitly unloading when opening build tools)
|
|
LLFloaterReg::showInstance("env_adjust_snapshot");
|
|
hdri_preview();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
class LLAdvancedClickGLTFOpen: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
static LLCachedControl<bool> can_use_shaders(gSavedSettings, "RenderCanUseGLTFPBROpaqueShaders", true);
|
|
if (can_use_shaders)
|
|
{
|
|
LL::GLTFSceneManager::instance().load();
|
|
}
|
|
else
|
|
{
|
|
LLNotificationsUtil::add("NoSupportGLTFShader");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedClickGLTFSaveAs : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LL::GLTFSceneManager::instance().saveAs();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedClickGLTFUpload: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LL::GLTFSceneManager::instance().uploadSelection();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedClickGLTFEdit : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLFloaterReg::showInstance("gltf_asset_editor");
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLAdvancedClickResizeWindow : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
S32 w = 0;
|
|
S32 h = 0;
|
|
|
|
sscanf(userdata.asString().c_str(), "%dx%d", &w, &h);
|
|
|
|
if (w > 0 && h > 0)
|
|
{
|
|
gViewerWindow->getWindow()->setSize(LLCoordWindow(w, h));
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
// these are used in the gl menus to set control values that require shader recompilation
|
|
class LLToggleShaderControl : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string control_name = userdata.asString();
|
|
bool checked = gSavedSettings.getBOOL( control_name );
|
|
gSavedSettings.setBOOL( control_name, !checked );
|
|
LLPipeline::refreshCachedSettings();
|
|
LLViewerShaderMgr::instance()->setShaders();
|
|
return !checked;
|
|
}
|
|
};
|
|
|
|
//[FIX FIRE-1927 - enable DoubleClickTeleport shortcut : SJ]
|
|
// This stuff is based on LLPanelPreferenceControls::setKeyBind() and LLPanelPreferenceControls::canKeyBindHandle()
|
|
void setDoubleClickAction(const std::string& control)
|
|
{
|
|
constexpr LLKeyConflictHandler::ESourceMode mode{ LLKeyConflictHandler::MODE_THIRD_PERSON };
|
|
constexpr EMouseClickType click{ EMouseClickType::CLICK_DOUBLELEFT };
|
|
constexpr KEY key{ KEY_NONE };
|
|
constexpr MASK mask{ MASK_NONE };
|
|
|
|
LLKeyConflictHandler conflictHandler;
|
|
conflictHandler.setLoadMode(mode);
|
|
conflictHandler.loadFromSettings(mode);
|
|
|
|
if (!conflictHandler.canAssignControl(control))
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool is_enabled = conflictHandler.canHandleControl(control, click, key, mask);
|
|
if (!is_enabled)
|
|
{
|
|
// find free spot to add data, if no free spot, assign to first
|
|
S32 index = 0;
|
|
for (S32 i = 0; i < 3; i++)
|
|
{
|
|
if (conflictHandler.getControl(control, i).isEmpty())
|
|
{
|
|
index = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
bool ignore_mask = true;
|
|
conflictHandler.registerControl(control, index, click, key, mask, ignore_mask);
|
|
FSCommon::report_to_nearby_chat(LLTrans::getString("DoubleClickTeleportEnabled"));
|
|
}
|
|
else
|
|
{
|
|
// find specific control and reset it
|
|
for (S32 i = 0; i < 3; i++)
|
|
{
|
|
LLKeyData data = conflictHandler.getControl(control, i);
|
|
if (data.mMouse == click && data.mKey == key && data.mMask == mask)
|
|
{
|
|
conflictHandler.clearControl(control, i);
|
|
FSCommon::report_to_nearby_chat(LLTrans::getString("DoubleClickTeleportDisabled"));
|
|
}
|
|
}
|
|
}
|
|
|
|
conflictHandler.saveToSettings();
|
|
}
|
|
|
|
bool isDoubleClickActionEnabled(const std::string& control)
|
|
{
|
|
constexpr LLKeyConflictHandler::ESourceMode mode{ LLKeyConflictHandler::MODE_THIRD_PERSON };
|
|
constexpr EMouseClickType click{ EMouseClickType::CLICK_DOUBLELEFT };
|
|
constexpr KEY key{ KEY_NONE };
|
|
constexpr MASK mask{ MASK_NONE };
|
|
|
|
LLKeyConflictHandler conflictHandler;
|
|
conflictHandler.loadFromSettings(mode);
|
|
|
|
return conflictHandler.canHandleControl(control, click, key, mask);
|
|
}
|
|
|
|
class FSAdvancedToggleDoubleClickAction: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
const std::string& control = userdata.asStringRef();
|
|
setDoubleClickAction(control);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class FSAdvancedCheckEnabledDoubleClickAction : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
const std::string& control = userdata.asStringRef();
|
|
return isDoubleClickActionEnabled(control);
|
|
}
|
|
};
|
|
|
|
// <FS:Beq> Add telemetry controls to the viewer menus
|
|
class FSProfilerToggle : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
#ifdef TRACY_ENABLE
|
|
bool checked = gSavedSettings.getBOOL("ProfilingActive");
|
|
gSavedSettings.setBOOL("ProfilingActive", !checked);
|
|
LLProfiler::active = !checked;
|
|
#endif
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class FSProfilerCheckEnabled : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
#ifdef TRACY_ENABLE
|
|
return true;
|
|
#else
|
|
return false;
|
|
#endif
|
|
}
|
|
};
|
|
// </FS:Beq>
|
|
|
|
void menu_toggle_attached_lights()
|
|
{
|
|
LLPipeline::sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights");
|
|
}
|
|
|
|
void menu_toggle_attached_particles()
|
|
{
|
|
LLPipeline::sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles");
|
|
}
|
|
|
|
class LLAdvancedHandleAttachedLightParticles: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string control_name = userdata.asString();
|
|
|
|
// toggle the control
|
|
gSavedSettings.setBOOL(control_name,
|
|
!gSavedSettings.getBOOL(control_name));
|
|
|
|
// update internal flags
|
|
// <FS:Ansariel> Make change to RenderAttachedLights & RenderAttachedParticles instant
|
|
//if (control_name == "RenderAttachedLights")
|
|
//{
|
|
// menu_toggle_attached_lights();
|
|
//}
|
|
//else if (control_name == "RenderAttachedParticles")
|
|
//{
|
|
// menu_toggle_attached_particles();
|
|
//}
|
|
// </FS:Ansariel>
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLSomethingSelected : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = !(LLSelectMgr::getInstance()->getSelection()->isEmpty());
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLSomethingSelectedNoHUD : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
|
|
bool new_value = !(selection->isEmpty()) && !(selection->getSelectType() == SELECT_TYPE_HUD);
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
static bool is_editable_selected()
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.0.5a
|
|
// Changed for Firestorm because of script reset function in object menus (see FIRE-8213)
|
|
if (rlv_handler_t::isEnabled())
|
|
{
|
|
LLObjectSelectionHandle hSelection = LLSelectMgr::getInstance()->getSelection();
|
|
|
|
// NOTE: this is called for 5 different menu items so we'll trade accuracy for efficiency and only
|
|
// examine root nodes (LLToolsSelectedScriptAction::handleEvent() will catch what we miss)
|
|
if (hSelection->isAttachment())
|
|
{
|
|
RlvSelectHasLockedAttach f;
|
|
if (gRlvAttachmentLocks.hasLockedAttachmentPoint(RLV_LOCK_REMOVE) && hSelection->getFirstRootNode(&f))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// RlvSelectIsEditable will sort out all editable objects
|
|
// => if result = NULL, we can't edit all selected objects
|
|
RlvSelectIsEditable f;
|
|
if (hSelection->getFirstRootNode(&f) != NULL)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
return (LLSelectMgr::getInstance()->getSelection()->getFirstEditableObject() != NULL);
|
|
}
|
|
|
|
class LLEditableSelected : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return is_editable_selected();
|
|
}
|
|
};
|
|
|
|
class LLEditableSelectedMono : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = false;
|
|
LLViewerRegion* region = gAgent.getRegion();
|
|
if(region && gMenuHolder)
|
|
{
|
|
bool have_cap = (! region->getCapability("UpdateScriptTask").empty());
|
|
new_value = is_editable_selected() && have_cap;
|
|
}
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
bool enable_object_take_copy()
|
|
{
|
|
bool all_valid = false;
|
|
if (LLSelectMgr::getInstance())
|
|
{
|
|
if (LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() > 0)
|
|
{
|
|
all_valid = true;
|
|
#ifndef HACKED_GODLIKE_VIEWER
|
|
# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
|
|
if (!LLGridManager::getInstance()->isInSLBeta()
|
|
|| !gAgent.isGodlike())
|
|
# endif
|
|
{
|
|
struct f : public LLSelectedObjectFunctor
|
|
{
|
|
virtual bool apply(LLViewerObject* obj)
|
|
{
|
|
// return (!obj->permCopy() || obj->isAttachment());
|
|
// [RLVa:KB] - Checked: 2010-04-01 (RLVa-1.2.0c) | Modified: RLVa-1.0.0g
|
|
return (!obj->permCopy() || obj->isAttachment()) ||
|
|
( (gRlvHandler.hasBehaviour(RLV_BHVR_UNSIT)) && (isAgentAvatarValid()) && (gAgentAvatarp->getRoot() == obj) );
|
|
// [/RLVa:KB]
|
|
}
|
|
} func;
|
|
const bool firstonly = true;
|
|
bool any_invalid = LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func, firstonly);
|
|
all_valid = !any_invalid;
|
|
}
|
|
#endif // HACKED_GODLIKE_VIEWER
|
|
}
|
|
}
|
|
|
|
return all_valid;
|
|
}
|
|
|
|
bool enable_take_copy_objects()
|
|
{
|
|
return enable_object_take_copy() && is_multiple_selection();
|
|
}
|
|
|
|
class LLHasAsset : public LLInventoryCollectFunctor
|
|
{
|
|
public:
|
|
LLHasAsset(const LLUUID& id) : mAssetID(id), mHasAsset(false) {}
|
|
virtual ~LLHasAsset() {}
|
|
virtual bool operator()(LLInventoryCategory* cat,
|
|
LLInventoryItem* item);
|
|
bool hasAsset() const { return mHasAsset; }
|
|
|
|
protected:
|
|
LLUUID mAssetID;
|
|
bool mHasAsset;
|
|
};
|
|
|
|
bool LLHasAsset::operator()(LLInventoryCategory* cat,
|
|
LLInventoryItem* item)
|
|
{
|
|
if(item && item->getAssetUUID() == mAssetID)
|
|
{
|
|
mHasAsset = true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
bool enable_save_into_task_inventory()
|
|
{
|
|
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstRootNode();
|
|
if(node && (node->mValid) && (!node->mFromTaskID.isNull()))
|
|
{
|
|
// *TODO: check to see if the fromtaskid object exists.
|
|
LLViewerObject* obj = node->getObject();
|
|
if( obj && !obj->isAttachment() )
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
class LLToolsEnableSaveToObjectInventory : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = enable_save_into_task_inventory();
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLToggleHowTo : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLFloaterReg::toggleInstanceOrBringToFront("guidebook");
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLViewEnableMouselook : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// You can't go directly from customize avatar to mouselook.
|
|
// TODO: write code with appropriate dialogs to handle this transition.
|
|
bool new_value = (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && !gSavedSettings.getBOOL("FreezeTime"));
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLToolsEnableToolNotPie : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = ( LLToolMgr::getInstance()->getBaseTool() != LLToolPie::getInstance() );
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLWorldEnableCreateLandmark : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// return !LLLandmarkActions::landmarkAlreadyExists();
|
|
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.4.5) | Added: RLVa-1.2.1
|
|
return (!LLLandmarkActions::landmarkAlreadyExists()) && (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC));
|
|
// [/RLVa:KB]
|
|
}
|
|
};
|
|
|
|
class LLWorldEnableSetHomeLocation : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gAgent.isGodlike() ||
|
|
(gAgent.getRegion() && gAgent.getRegion()->getAllowSetHome());
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLWorldEnableTeleportHome : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLViewerRegion* regionp = gAgent.getRegion();
|
|
bool agent_on_prelude = (regionp && regionp->isPrelude());
|
|
bool enable_teleport_home = gAgent.isGodlike() || !agent_on_prelude;
|
|
// [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.2.1f
|
|
enable_teleport_home &=
|
|
(!rlv_handler_t::isEnabled()) || ((!gRlvHandler.hasBehaviour(RLV_BHVR_TPLM)) && (!gRlvHandler.hasBehaviour(RLV_BHVR_TPLOC)));
|
|
// [/RLVa:KB]
|
|
return enable_teleport_home;
|
|
}
|
|
};
|
|
|
|
bool enable_god_full()
|
|
{
|
|
return gAgent.getGodLevel() >= GOD_FULL;
|
|
}
|
|
|
|
bool enable_god_liaison()
|
|
{
|
|
return gAgent.getGodLevel() >= GOD_LIAISON;
|
|
}
|
|
|
|
bool is_god_customer_service()
|
|
{
|
|
return gAgent.getGodLevel() >= GOD_CUSTOMER_SERVICE;
|
|
}
|
|
|
|
bool enable_god_basic()
|
|
{
|
|
return gAgent.getGodLevel() > GOD_NOT;
|
|
}
|
|
|
|
|
|
void toggle_show_xui_names()
|
|
{
|
|
gSavedSettings.setBOOL("DebugShowXUINames", !gSavedSettings.getBOOL("DebugShowXUINames"));
|
|
}
|
|
|
|
bool check_show_xui_names()
|
|
{
|
|
return gSavedSettings.getBOOL("DebugShowXUINames");
|
|
}
|
|
|
|
// <FS:CR> Resync Animations
|
|
class FSToolsResyncAnimations : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
for (S32 i = 0; i < gObjectList.getNumObjects(); i++)
|
|
{
|
|
LLViewerObject* object = gObjectList.getObject(i);
|
|
if (object &&
|
|
object->isAvatar())
|
|
{
|
|
LLVOAvatar* avatarp = (LLVOAvatar*)object;
|
|
if (avatarp)
|
|
{
|
|
for (LLVOAvatar::AnimIterator anim_it = avatarp->mPlayingAnimations.begin();
|
|
anim_it != avatarp->mPlayingAnimations.end();
|
|
anim_it++)
|
|
{
|
|
avatarp->stopMotion(anim_it->first, true);
|
|
avatarp->startMotion(anim_it->first);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:CR> Resync Animations
|
|
|
|
// <FS:CR> FIRE-4345: Undeform
|
|
class FSToolsUndeform : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (isAgentAvatarValid())
|
|
{
|
|
gAgentAvatarp->resetSkeleton(true);
|
|
|
|
FSPose::getInstance()->setPose(gSavedSettings.getString("FSUndeformUUID"), false);
|
|
gAgentAvatarp->updateVisualParams();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:CR> FIRE-4345: Undeform
|
|
|
|
// <FS:CR> Stream list import/export
|
|
class FSStreamListExportXML :public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLFilePicker& file_picker = LLFilePicker::instance();
|
|
if(file_picker.getSaveFile(LLFilePicker::FFSAVE_XML, LLDir::getScrubbedFileName("stream_list.xml")))
|
|
{
|
|
std::string filename = file_picker.getFirstFile();
|
|
llofstream export_file(filename.c_str());
|
|
LLSDSerialize::toPrettyXML(gSavedSettings.getLLSD("FSStreamList"), export_file);
|
|
export_file.close();
|
|
LLSD args;
|
|
args["FILENAME"] = filename;
|
|
LLNotificationsUtil::add("StreamListExportSuccess", args);
|
|
}
|
|
else
|
|
LL_INFOS() << "User closed the filepicker. Aborting!" << LL_ENDL;
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class FSStreamListImportXML :public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLFilePicker& file_picker = LLFilePicker::instance();
|
|
if(file_picker.getOpenFile(LLFilePicker::FFLOAD_XML))
|
|
{
|
|
std::string filename = file_picker.getFirstFile();
|
|
llifstream stream_list(filename.c_str());
|
|
if(!stream_list.is_open())
|
|
{
|
|
LL_WARNS() << "Couldn't open the xml file for reading. Aborting import!" << LL_ENDL;
|
|
return true;
|
|
}
|
|
LLSD stream_data;
|
|
if(LLSDSerialize::fromXML(stream_data, stream_list) >= 1)
|
|
{
|
|
gSavedSettings.setLLSD("FSStreamList", stream_data);
|
|
LLNotificationsUtil::add("StreamListImportSuccess");
|
|
}
|
|
stream_list.close();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:CR> Stream list import/export
|
|
|
|
// <FS:CR> Dump SimulatorFeatures to chat
|
|
class FSDumpSimulatorFeaturesToChat : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (LLViewerRegion* region = gAgent.getRegion())
|
|
{
|
|
LLSD sim_features;
|
|
std::stringstream out_str;
|
|
region->getSimulatorFeatures(sim_features);
|
|
LLSDSerialize::toPrettyXML(sim_features, out_str);
|
|
FSCommon::report_to_nearby_chat(out_str.str());
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:CR> Dump SimulatorFeatures to chat
|
|
|
|
// <FS:CR> Add to contact set
|
|
class FSAddToContactSet : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
if (!rlv_handler_t::isEnabled() || !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWNAMES))
|
|
{
|
|
LLVOAvatar* avatarp = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
|
|
if (avatarp)
|
|
{
|
|
LLFloaterReg::showInstance("fs_add_contact", LLSD(avatarp->getID()), true);
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:CR> Add to contact set
|
|
|
|
// <FS:CR> Opensim menu item visibility control
|
|
bool checkIsGrid(const LLSD& userdata)
|
|
{
|
|
std::string grid_type = userdata.asString();
|
|
if ("secondlife" == grid_type)
|
|
{
|
|
return LLGridManager::getInstance()->isInSecondLife();
|
|
}
|
|
#ifdef OPENSIM
|
|
else if ("opensim" == grid_type)
|
|
{
|
|
return LLGridManager::getInstance()->isInOpenSim();
|
|
}
|
|
else if ("aurorasim" == grid_type)
|
|
{
|
|
return LLGridManager::getInstance()->isInAuroraSim();
|
|
}
|
|
#else // !OPENSIM
|
|
else if ("opensim" == grid_type || "aurorasim" == grid_type)
|
|
{
|
|
LL_DEBUGS("ViewerMenu") << grid_type << "is not a supported platform on Havok builds. Disabling item." << LL_ENDL;
|
|
return false;
|
|
}
|
|
#endif // OPENSIM
|
|
else
|
|
{
|
|
LL_WARNS("ViewerMenu") << "Unhandled or bad on_visible gridcheck parameter! (" << grid_type << ")" << LL_ENDL;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool isGridFeatureEnabled(const LLSD& userdata)
|
|
{
|
|
if (LFSimFeatureHandler::instanceExists())
|
|
{
|
|
const std::string feature = userdata.asString();
|
|
|
|
if (feature == "avatar_picker")
|
|
{
|
|
return LFSimFeatureHandler::instance().hasAvatarPicker();
|
|
}
|
|
else if (feature == "destination_guide")
|
|
{
|
|
return LFSimFeatureHandler::instance().hasDestinationGuide();
|
|
}
|
|
else
|
|
{
|
|
LL_WARNS("ViewerMenu") << "Unhandled or bad grid feature check parameter! (" << feature << ")" << LL_ENDL;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
// </FS:CR>
|
|
|
|
// <FS:Ansariel> FIRE-21236 - Help Menu - Check Grid Status doesn't open using External Browser
|
|
void openGridStatus()
|
|
{
|
|
if (LLWeb::useExternalBrowser(LFSimFeatureHandler::instance().gridStatusURL()))
|
|
{
|
|
LLWeb::loadURLExternal(LFSimFeatureHandler::instance().gridStatusURL());
|
|
}
|
|
else
|
|
{
|
|
LLFloaterReg::toggleInstance("grid_status");
|
|
}
|
|
}
|
|
// </FS:Ansariel>
|
|
|
|
class LLToolsSelectOnlyMyObjects : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool cur_val = gSavedSettings.getBOOL("SelectOwnedOnly");
|
|
|
|
gSavedSettings.setBOOL("SelectOwnedOnly", ! cur_val );
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToolsSelectOnlyMovableObjects : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool cur_val = gSavedSettings.getBOOL("SelectMovableOnly");
|
|
|
|
gSavedSettings.setBOOL("SelectMovableOnly", ! cur_val );
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToolsSelectInvisibleObjects : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool cur_val = gSavedSettings.getBOOL("SelectInvisibleObjects");
|
|
|
|
gSavedSettings.setBOOL("SelectInvisibleObjects", !cur_val);
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToolsSelectReflectionProbes: public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool cur_val = gSavedSettings.getBOOL("SelectReflectionProbes");
|
|
|
|
gSavedSettings.setBOOL("SelectReflectionProbes", !cur_val);
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToolsSelectBySurrounding : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLSelectMgr::sRectSelectInclusive = !LLSelectMgr::sRectSelectInclusive;
|
|
|
|
gSavedSettings.setBOOL("RectangleSelectInclusive", LLSelectMgr::sRectSelectInclusive);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToolsShowHiddenSelection : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// TomY TODO Merge these
|
|
LLSelectMgr::sRenderHiddenSelections = !LLSelectMgr::sRenderHiddenSelections;
|
|
|
|
gSavedSettings.setBOOL("RenderHiddenSelections", LLSelectMgr::sRenderHiddenSelections);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToolsShowSelectionLightRadius : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// TomY TODO merge these
|
|
LLSelectMgr::sRenderLightRadius = !LLSelectMgr::sRenderLightRadius;
|
|
|
|
gSavedSettings.setBOOL("RenderLightRadius", LLSelectMgr::sRenderLightRadius);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToolsEditLinkedParts : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool select_individuals = !gSavedSettings.getBOOL("EditLinkedParts");
|
|
gSavedSettings.setBOOL( "EditLinkedParts", select_individuals );
|
|
if (select_individuals)
|
|
{
|
|
LLSelectMgr::getInstance()->demoteSelectionToIndividuals();
|
|
}
|
|
else
|
|
{
|
|
LLSelectMgr::getInstance()->promoteSelectionToRoot();
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
void reload_vertex_shader()
|
|
{
|
|
//THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought - DaveP
|
|
}
|
|
|
|
void handle_dump_avatar_local_textures()
|
|
{
|
|
gAgentAvatarp->dumpLocalTextures();
|
|
}
|
|
|
|
void handle_dump_timers()
|
|
{
|
|
LLTrace::BlockTimer::dumpCurTimes();
|
|
}
|
|
|
|
void handle_debug_avatar_textures()
|
|
{
|
|
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (objectp)
|
|
{
|
|
LLFloaterReg::showInstance( "avatar_textures", LLSD(objectp->getID()) );
|
|
}
|
|
}
|
|
|
|
void handle_grab_baked_texture(EBakedTextureIndex baked_tex_index)
|
|
{
|
|
if (!isAgentAvatarValid())
|
|
return;
|
|
|
|
const LLUUID& asset_id = gAgentAvatarp->grabBakedTexture(baked_tex_index);
|
|
LL_INFOS("texture") << "Adding baked texture " << asset_id << " to inventory." << LL_ENDL;
|
|
LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE;
|
|
LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE;
|
|
const LLUUID folder_id = gInventory.findCategoryUUIDForType(LLFolderType::assetTypeToFolderType(asset_type));
|
|
if(folder_id.notNull())
|
|
{
|
|
std::string name;
|
|
name = "Baked " + LLAvatarAppearance::getDictionary()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
|
|
|
|
LLUUID item_id;
|
|
item_id.generate();
|
|
LLPermissions perm;
|
|
perm.init(gAgentID,
|
|
gAgentID,
|
|
LLUUID::null,
|
|
LLUUID::null);
|
|
U32 next_owner_perm = PERM_MOVE | PERM_TRANSFER;
|
|
perm.initMasks(PERM_ALL,
|
|
PERM_ALL,
|
|
PERM_NONE,
|
|
PERM_NONE,
|
|
next_owner_perm);
|
|
time_t creation_date_now = time_corrected();
|
|
LLPointer<LLViewerInventoryItem> item
|
|
= new LLViewerInventoryItem(item_id,
|
|
folder_id,
|
|
perm,
|
|
asset_id,
|
|
asset_type,
|
|
inv_type,
|
|
name,
|
|
LLStringUtil::null,
|
|
LLSaleInfo::DEFAULT,
|
|
LLInventoryItemFlags::II_FLAGS_NONE,
|
|
creation_date_now);
|
|
|
|
item->updateServer(true);
|
|
gInventory.updateItem(item);
|
|
gInventory.notifyObservers();
|
|
|
|
// Show the preview panel for textures to let
|
|
// user know that the image is now in inventory.
|
|
LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
|
|
if(active_panel)
|
|
{
|
|
LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus();
|
|
|
|
active_panel->setSelection(item_id, TAKE_FOCUS_NO);
|
|
active_panel->openSelected();
|
|
//LLFloaterInventory::dumpSelectionInformation((void*)view);
|
|
// restore keyboard focus
|
|
gFocusMgr.setKeyboardFocus(focus_ctrl);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
LL_WARNS() << "Can't find a folder to put it in" << LL_ENDL;
|
|
}
|
|
}
|
|
|
|
bool enable_grab_baked_texture(EBakedTextureIndex baked_tex_index)
|
|
{
|
|
if (isAgentAvatarValid())
|
|
{
|
|
return gAgentAvatarp->canGrabBakedTexture(baked_tex_index);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// Returns a pointer to the avatar give the UUID of the avatar OR of an attachment the avatar is wearing.
|
|
// Returns NULL on failure.
|
|
LLVOAvatar* find_avatar_from_object(LLViewerObject* object)
|
|
{
|
|
if (object)
|
|
{
|
|
if( object->isAttachment() )
|
|
{
|
|
do
|
|
{
|
|
object = (LLViewerObject*) object->getParent();
|
|
}
|
|
while( object && !object->isAvatar() );
|
|
}
|
|
else if( !object->isAvatar() )
|
|
{
|
|
object = NULL;
|
|
}
|
|
}
|
|
|
|
return (LLVOAvatar*) object;
|
|
}
|
|
|
|
|
|
// Returns a pointer to the avatar give the UUID of the avatar OR of an attachment the avatar is wearing.
|
|
// Returns NULL on failure.
|
|
LLVOAvatar* find_avatar_from_object(const LLUUID& object_id)
|
|
{
|
|
return find_avatar_from_object( gObjectList.findObject(object_id) );
|
|
}
|
|
|
|
|
|
void handle_disconnect_viewer()
|
|
{
|
|
LLAppViewer::instance()->forceDisconnect(LLTrans::getString("TestingDisconnect"));
|
|
}
|
|
|
|
void force_error_breakpoint()
|
|
{
|
|
LLAppViewer::instance()->forceErrorBreakpoint();
|
|
}
|
|
|
|
void force_error_llerror()
|
|
{
|
|
LLAppViewer::instance()->forceErrorLLError();
|
|
}
|
|
|
|
void force_error_llerror_msg()
|
|
{
|
|
LLAppViewer::instance()->forceErrorLLErrorMsg();
|
|
}
|
|
|
|
void force_error_bad_memory_access()
|
|
{
|
|
LLAppViewer::instance()->forceErrorBadMemoryAccess();
|
|
}
|
|
|
|
void force_error_infinite_loop()
|
|
{
|
|
LLAppViewer::instance()->forceErrorInfiniteLoop();
|
|
}
|
|
|
|
void force_error_software_exception()
|
|
{
|
|
LLAppViewer::instance()->forceErrorSoftwareException();
|
|
}
|
|
|
|
void force_error_os_exception()
|
|
{
|
|
LLAppViewer::instance()->forceErrorOSSpecificException();
|
|
}
|
|
|
|
void force_error_driver_crash()
|
|
{
|
|
LLAppViewer::instance()->forceErrorDriverCrash();
|
|
}
|
|
|
|
// <FS:Ansariel> Wrongly merged back in by LL
|
|
//void force_error_coroutine_crash()
|
|
//{
|
|
// LLAppViewer::instance()->forceErrorCoroutineCrash();
|
|
//}
|
|
// </FS:Ansariel>
|
|
|
|
void force_error_thread_crash()
|
|
{
|
|
LLAppViewer::instance()->forceErrorThreadCrash();
|
|
}
|
|
|
|
class LLToolsUseSelectionForGrid : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLSelectMgr::getInstance()->clearGridObjects();
|
|
struct f : public LLSelectedObjectFunctor
|
|
{
|
|
virtual bool apply(LLViewerObject* objectp)
|
|
{
|
|
LLSelectMgr::getInstance()->addGridObject(objectp);
|
|
return true;
|
|
}
|
|
} func;
|
|
LLSelectMgr::getInstance()->getSelection()->applyToRootObjects(&func);
|
|
LLSelectMgr::getInstance()->setGridMode(GRID_MODE_REF_OBJECT);
|
|
LLFloaterTools::setGridMode((S32)GRID_MODE_REF_OBJECT);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
void handle_test_load_url()
|
|
{
|
|
LLWeb::loadURL("");
|
|
LLWeb::loadURL("hacker://www.google.com/");
|
|
LLWeb::loadURL("http");
|
|
LLWeb::loadURL("http://www.google.com/");
|
|
}
|
|
|
|
//
|
|
// LLViewerMenuHolderGL
|
|
//
|
|
static LLDefaultChildRegistry::Register<LLViewerMenuHolderGL> r("menu_holder");
|
|
|
|
LLViewerMenuHolderGL::LLViewerMenuHolderGL(const LLViewerMenuHolderGL::Params& p)
|
|
: LLMenuHolderGL(p)
|
|
{}
|
|
|
|
bool LLViewerMenuHolderGL::hideMenus()
|
|
{
|
|
bool handled = false;
|
|
|
|
if (LLMenuHolderGL::hideMenus())
|
|
{
|
|
handled = true;
|
|
}
|
|
|
|
// drop pie menu selection
|
|
mParcelSelection = NULL;
|
|
mObjectSelection = NULL;
|
|
|
|
if (gMenuBarView)
|
|
{
|
|
gMenuBarView->clearHoverItem();
|
|
gMenuBarView->resetMenuTrigger();
|
|
}
|
|
|
|
return handled;
|
|
}
|
|
|
|
void LLViewerMenuHolderGL::setParcelSelection(LLSafeHandle<LLParcelSelection> selection)
|
|
{
|
|
mParcelSelection = selection;
|
|
}
|
|
|
|
void LLViewerMenuHolderGL::setObjectSelection(LLSafeHandle<LLObjectSelection> selection)
|
|
{
|
|
mObjectSelection = selection;
|
|
}
|
|
|
|
|
|
const LLRect LLViewerMenuHolderGL::getMenuRect() const
|
|
{
|
|
return LLRect(0, getRect().getHeight() - MENU_BAR_HEIGHT, getRect().getWidth(), STATUS_BAR_HEIGHT);
|
|
}
|
|
|
|
void handle_save_to_xml(void*)
|
|
{
|
|
LLFloater* frontmost = gFloaterView->getFrontmost();
|
|
if (!frontmost)
|
|
{
|
|
LLNotificationsUtil::add("NoFrontmostFloater");
|
|
return;
|
|
}
|
|
|
|
std::string default_name = "floater_";
|
|
default_name += frontmost->getTitle();
|
|
default_name += ".xml";
|
|
|
|
LLStringUtil::toLower(default_name);
|
|
LLStringUtil::replaceChar(default_name, ' ', '_');
|
|
LLStringUtil::replaceChar(default_name, '/', '_');
|
|
LLStringUtil::replaceChar(default_name, ':', '_');
|
|
LLStringUtil::replaceChar(default_name, '"', '_');
|
|
|
|
LLFilePicker& picker = LLFilePicker::instance();
|
|
if (picker.getSaveFile(LLFilePicker::FFSAVE_XML, default_name))
|
|
{
|
|
std::string filename = picker.getFirstFile();
|
|
LLUICtrlFactory::getInstance()->saveToXML(frontmost, filename);
|
|
}
|
|
}
|
|
|
|
void handle_load_from_xml(void*)
|
|
{
|
|
LLFilePicker& picker = LLFilePicker::instance();
|
|
if (picker.getOpenFile(LLFilePicker::FFLOAD_XML))
|
|
{
|
|
std::string filename = picker.getFirstFile();
|
|
LLFloater* floater = new LLFloater(LLSD());
|
|
floater->buildFromFile(filename);
|
|
}
|
|
}
|
|
|
|
void handle_web_browser_test(const LLSD& param)
|
|
{
|
|
std::string url = param.asString();
|
|
if (url.empty())
|
|
{
|
|
url = "about:blank";
|
|
}
|
|
LLWeb::loadURLInternal(url);
|
|
}
|
|
|
|
bool callback_clear_cache_immediately(const LLSD& notification, const LLSD& response)
|
|
{
|
|
S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
|
|
if ( option == 0 ) // YES
|
|
{
|
|
//clear cache
|
|
LLAppViewer::instance()->purgeCacheImmediate();
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void handle_cache_clear_immediately()
|
|
{
|
|
LLNotificationsUtil::add("ConfirmClearCache", LLSD(), LLSD(), callback_clear_cache_immediately);
|
|
}
|
|
|
|
void handle_web_content_test(const LLSD& param)
|
|
{
|
|
std::string url = param.asString();
|
|
// <FS:LO> Add a user settable home page for the built in web browser
|
|
if (url == "HOME_PAGE")
|
|
{
|
|
url = gSavedSettings.getString("FSBrowserHomePage");
|
|
}
|
|
// </FS:LO>
|
|
LLWeb::loadURLInternal(url, LLStringUtil::null, LLStringUtil::null, true);
|
|
}
|
|
|
|
void handle_show_url(const LLSD& param)
|
|
{
|
|
std::string url = param.asString();
|
|
if (LLWeb::useExternalBrowser(url))
|
|
{
|
|
LLWeb::loadURLExternal(url);
|
|
}
|
|
else
|
|
{
|
|
LLWeb::loadURLInternal(url);
|
|
}
|
|
|
|
}
|
|
|
|
void handle_report_bug(const LLSD& param)
|
|
{
|
|
// <FS:Ansariel> Keep linking to out JIRA
|
|
//std::string url = gSavedSettings.getString("ReportBugURL");
|
|
//LLWeb::loadURLExternal(url);
|
|
LLSD sysinfo = FSData::getSystemInfo();
|
|
LLStringUtil::format_map_t replace;
|
|
replace["[ENVIRONMENT]"] = LLURI::escape(sysinfo["Part1"].asString().substr(1) + sysinfo["Part2"].asString().substr(1));
|
|
LLSLURL location_url;
|
|
LLAgentUI::buildSLURL(location_url);
|
|
replace["[LOCATION]"] = LLURI::escape(location_url.getSLURLString());
|
|
|
|
LLUIString file_bug_url = gSavedSettings.getString("ReportBugURL");
|
|
file_bug_url.setArgs(replace);
|
|
|
|
LLWeb::loadURLExternal(file_bug_url.getString());
|
|
// </FS:Ansariel>
|
|
}
|
|
|
|
void handle_buy_currency_test()
|
|
{
|
|
std::string url =
|
|
"http://sarahd-sl-13041.webdev.lindenlab.com/app/lindex/index.php?agent_id=[AGENT_ID]&secure_session_id=[SESSION_ID]&lang=[LANGUAGE]";
|
|
|
|
LLStringUtil::format_map_t replace;
|
|
replace["[AGENT_ID]"] = gAgent.getID().asString();
|
|
replace["[SESSION_ID]"] = gAgent.getSecureSessionID().asString();
|
|
replace["[LANGUAGE]"] = LLUI::getLanguage();
|
|
LLStringUtil::format(url, replace);
|
|
|
|
LL_INFOS() << "buy currency url " << url << LL_ENDL;
|
|
|
|
LLFloaterReg::showInstance("buy_currency_html", LLSD(url));
|
|
}
|
|
|
|
//-- SUNSHINE CLEANUP - is only the request update at the end needed now?
|
|
void handle_rebake_textures()
|
|
{
|
|
if (!isAgentAvatarValid()) return;
|
|
|
|
// Slam pending upload count to "unstick" things
|
|
bool slam_for_debug = true;
|
|
gAgentAvatarp->forceBakeAllTextures(slam_for_debug);
|
|
if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
|
|
{
|
|
// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-06-27 (Catznip-3.7)
|
|
if (!gAgent.getRegionCapability("IncrementCOFVersion").empty())
|
|
{
|
|
LLAppearanceMgr::instance().syncCofVersionAndRefresh();
|
|
}
|
|
else
|
|
{
|
|
LLAppearanceMgr::instance().requestServerAppearanceUpdate();
|
|
}
|
|
// [/SL:KB]
|
|
// LLAppearanceMgr::instance().requestServerAppearanceUpdate();
|
|
avatar_tex_refresh(gAgentAvatarp); // <FS:CR> FIRE-11800 - Refresh the textures too
|
|
}
|
|
reset_mesh_lod(gAgentAvatarp); // <FS:Ansariel> Reset Mesh LOD
|
|
gAgentAvatarp->setIsCrossingRegion(false); // <FS:Ansariel> FIRE-12004: Attachments getting lost on TP
|
|
}
|
|
|
|
void toggle_visibility(LLView* viewp)
|
|
{
|
|
viewp->setVisible(!viewp->getVisible());
|
|
}
|
|
|
|
bool get_visibility(LLView* viewp)
|
|
{
|
|
return viewp->getVisible();
|
|
}
|
|
|
|
class LLViewShowHoverTips : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gSavedSettings.setBOOL("ShowHoverTips", !gSavedSettings.getBOOL("ShowHoverTips"));
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLViewCheckShowHoverTips : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = gSavedSettings.getBOOL("ShowHoverTips");
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLViewHighlightTransparent : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha;
|
|
// [RLVa:KB] - @edit and @viewtransparent
|
|
LLDrawPoolAlpha::sShowDebugAlpha = (!LLDrawPoolAlpha::sShowDebugAlpha) && (RlvActions::canHighlightTransparent());
|
|
// [/RLVa:KB]
|
|
|
|
// invisible objects skip building their render batches unless sShowDebugAlpha is true, so rebuild batches whenever toggling this flag
|
|
gPipeline.rebuildDrawInfo();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLViewCheckHighlightTransparent : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLDrawPoolAlpha::sShowDebugAlpha;
|
|
return new_value;
|
|
}
|
|
};
|
|
// <FS:Beq> FIRE-32132 et al. Allow rigged mesh transparency highlights to be toggled
|
|
class LLViewHighlightTransparentRigged : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLDrawPoolAlpha::sShowDebugAlphaRigged = !LLDrawPoolAlpha::sShowDebugAlphaRigged;
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLViewCheckHighlightTransparentRigged : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLDrawPoolAlpha::sShowDebugAlphaRigged;
|
|
return new_value;
|
|
}
|
|
};
|
|
// </FS:Beq>
|
|
|
|
class LLViewBeaconWidth : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string width = userdata.asString();
|
|
if(width == "1")
|
|
{
|
|
gSavedSettings.setS32("DebugBeaconLineWidth", 1);
|
|
}
|
|
else if(width == "4")
|
|
{
|
|
gSavedSettings.setS32("DebugBeaconLineWidth", 4);
|
|
}
|
|
else if(width == "16")
|
|
{
|
|
gSavedSettings.setS32("DebugBeaconLineWidth", 16);
|
|
}
|
|
else if(width == "32")
|
|
{
|
|
gSavedSettings.setS32("DebugBeaconLineWidth", 32);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
|
|
class LLViewToggleBeacon : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string beacon = userdata.asString();
|
|
if (beacon == "scriptsbeacon")
|
|
{
|
|
LLPipeline::toggleRenderScriptedBeacons();
|
|
gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() );
|
|
// toggle the other one off if it's on
|
|
if (LLPipeline::getRenderScriptedBeacons() && LLPipeline::getRenderScriptedTouchBeacons())
|
|
{
|
|
LLPipeline::toggleRenderScriptedTouchBeacons();
|
|
gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons() );
|
|
}
|
|
}
|
|
else if (beacon == "physicalbeacon")
|
|
{
|
|
LLPipeline::toggleRenderPhysicalBeacons();
|
|
gSavedSettings.setBOOL( "physicalbeacon", LLPipeline::getRenderPhysicalBeacons() );
|
|
}
|
|
else if (beacon == "moapbeacon")
|
|
{
|
|
LLPipeline::toggleRenderMOAPBeacons();
|
|
gSavedSettings.setBOOL( "moapbeacon", LLPipeline::getRenderMOAPBeacons() );
|
|
}
|
|
else if (beacon == "soundsbeacon")
|
|
{
|
|
LLPipeline::toggleRenderSoundBeacons();
|
|
gSavedSettings.setBOOL( "soundsbeacon", LLPipeline::getRenderSoundBeacons() );
|
|
}
|
|
else if (beacon == "particlesbeacon")
|
|
{
|
|
LLPipeline::toggleRenderParticleBeacons();
|
|
gSavedSettings.setBOOL( "particlesbeacon", LLPipeline::getRenderParticleBeacons() );
|
|
}
|
|
else if (beacon == "scripttouchbeacon")
|
|
{
|
|
LLPipeline::toggleRenderScriptedTouchBeacons();
|
|
gSavedSettings.setBOOL( "scripttouchbeacon", LLPipeline::getRenderScriptedTouchBeacons() );
|
|
// toggle the other one off if it's on
|
|
if (LLPipeline::getRenderScriptedBeacons() && LLPipeline::getRenderScriptedTouchBeacons())
|
|
{
|
|
LLPipeline::toggleRenderScriptedBeacons();
|
|
gSavedSettings.setBOOL( "scriptsbeacon", LLPipeline::getRenderScriptedBeacons() );
|
|
}
|
|
}
|
|
else if (beacon == "sunbeacon")
|
|
{
|
|
gSavedSettings.setBOOL("sunbeacon", !gSavedSettings.getBOOL("sunbeacon"));
|
|
}
|
|
else if (beacon == "moonbeacon")
|
|
{
|
|
gSavedSettings.setBOOL("moonbeacon", !gSavedSettings.getBOOL("moonbeacon"));
|
|
}
|
|
else if (beacon == "renderbeacons")
|
|
{
|
|
LLPipeline::toggleRenderBeacons();
|
|
gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons() );
|
|
// toggle the other one on if it's not
|
|
if (!LLPipeline::getRenderBeacons() && !LLPipeline::getRenderHighlights())
|
|
{
|
|
LLPipeline::toggleRenderHighlights();
|
|
gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights() );
|
|
}
|
|
}
|
|
else if (beacon == "renderhighlights")
|
|
{
|
|
LLPipeline::toggleRenderHighlights();
|
|
gSavedSettings.setBOOL( "renderhighlights", LLPipeline::getRenderHighlights() );
|
|
// toggle the other one on if it's not
|
|
if (!LLPipeline::getRenderBeacons() && !LLPipeline::getRenderHighlights())
|
|
{
|
|
LLPipeline::toggleRenderBeacons();
|
|
gSavedSettings.setBOOL( "renderbeacons", LLPipeline::getRenderBeacons() );
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLViewCheckBeaconEnabled : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string beacon = userdata.asString();
|
|
bool new_value = false;
|
|
if (beacon == "scriptsbeacon")
|
|
{
|
|
new_value = gSavedSettings.getBOOL( "scriptsbeacon");
|
|
LLPipeline::setRenderScriptedBeacons(new_value);
|
|
}
|
|
else if (beacon == "moapbeacon")
|
|
{
|
|
new_value = gSavedSettings.getBOOL( "moapbeacon");
|
|
LLPipeline::setRenderMOAPBeacons(new_value);
|
|
}
|
|
else if (beacon == "physicalbeacon")
|
|
{
|
|
new_value = gSavedSettings.getBOOL( "physicalbeacon");
|
|
LLPipeline::setRenderPhysicalBeacons(new_value);
|
|
}
|
|
else if (beacon == "soundsbeacon")
|
|
{
|
|
new_value = gSavedSettings.getBOOL( "soundsbeacon");
|
|
LLPipeline::setRenderSoundBeacons(new_value);
|
|
}
|
|
else if (beacon == "particlesbeacon")
|
|
{
|
|
new_value = gSavedSettings.getBOOL( "particlesbeacon");
|
|
LLPipeline::setRenderParticleBeacons(new_value);
|
|
}
|
|
else if (beacon == "scripttouchbeacon")
|
|
{
|
|
new_value = gSavedSettings.getBOOL( "scripttouchbeacon");
|
|
LLPipeline::setRenderScriptedTouchBeacons(new_value);
|
|
}
|
|
else if (beacon == "renderbeacons")
|
|
{
|
|
new_value = gSavedSettings.getBOOL( "renderbeacons");
|
|
LLPipeline::setRenderBeacons(new_value);
|
|
}
|
|
else if (beacon == "renderhighlights")
|
|
{
|
|
new_value = gSavedSettings.getBOOL( "renderhighlights");
|
|
LLPipeline::setRenderHighlights(new_value);
|
|
}
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLViewToggleRenderType : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string type = userdata.asString();
|
|
if (type == "hideparticles")
|
|
{
|
|
LLPipeline::toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
|
|
gPipeline.sRenderParticles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLViewCheckRenderType : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string type = userdata.asString();
|
|
bool new_value = false;
|
|
if (type == "hideparticles")
|
|
{
|
|
new_value = LLPipeline::toggleRenderTypeControlNegated(LLPipeline::RENDER_TYPE_PARTICLES);
|
|
}
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
class LLViewStatusAway : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return (gAgent.isInitialized() && gAgent.getAFK());
|
|
}
|
|
};
|
|
|
|
class LLViewStatusDoNotDisturb : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
return (gAgent.isInitialized() && gAgent.isDoNotDisturb());
|
|
}
|
|
};
|
|
|
|
class LLViewShowHUDAttachments : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// [RLVa:KB] - Checked: 2010-04-19 (RLVa-1.2.1a) | Modified: RLVa-1.0.0c
|
|
if ( (rlv_handler_t::isEnabled()) && (gRlvAttachmentLocks.hasLockedHUD()) && (LLPipeline::sShowHUDAttachments) )
|
|
return true;
|
|
// [/RLVa:KB]
|
|
|
|
LLPipeline::sShowHUDAttachments = !LLPipeline::sShowHUDAttachments;
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLViewCheckHUDAttachments : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool new_value = LLPipeline::sShowHUDAttachments;
|
|
return new_value;
|
|
}
|
|
};
|
|
|
|
// <FS:Ansariel> Disable Show HUD attachments if prevented by RLVa
|
|
bool enable_show_HUD_attachments()
|
|
{
|
|
return (!LLPipeline::sShowHUDAttachments || !rlv_handler_t::isEnabled() || !gRlvAttachmentLocks.hasLockedHUD());
|
|
};
|
|
// </FS:Ansariel>
|
|
|
|
class LLEditEnableTakeOff : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string clothing = userdata.asString();
|
|
LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing);
|
|
// if (type >= LLWearableType::WT_SHAPE && type < LLWearableType::WT_COUNT)
|
|
// [RLVa:KB] - Checked: 2010-03-20 (RLVa-1.2.0c) | Modified: RLVa-1.2.0a
|
|
// NOTE: see below - enable if there is at least one wearable on this type that can be removed
|
|
if ( (type >= LLWearableType::WT_SHAPE && type < LLWearableType::WT_COUNT) &&
|
|
((!rlv_handler_t::isEnabled()) || (gRlvWearableLocks.canRemove(type))) )
|
|
// [/RLVa:KB]
|
|
{
|
|
return LLAgentWearables::selfHasWearable(type);
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
|
|
// <FS:Beq> Xmas present for Ansa, Animesh kill switch
|
|
class FSDerenderAnimatedObjects : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
gObjectList.killAnimatedObjects();
|
|
return true;
|
|
}
|
|
};
|
|
|
|
// </FS:Beq>
|
|
class LLEditTakeOff : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string clothing = userdata.asString();
|
|
if (clothing == "all")
|
|
LLAppearanceMgr::instance().removeAllClothesFromAvatar();
|
|
else
|
|
{
|
|
LLWearableType::EType type = LLWearableType::getInstance()->typeNameToType(clothing);
|
|
if (type >= LLWearableType::WT_SHAPE
|
|
&& type < LLWearableType::WT_COUNT
|
|
&& (gAgentWearables.getWearableCount(type) > 0))
|
|
{
|
|
// MULTI-WEARABLES: assuming user wanted to remove top shirt.
|
|
//<FS:TS> Shut the compiler up about unsigned comparisons <0 or >0
|
|
//U32 wearable_index = gAgentWearables.getWearableCount(type) - 1;
|
|
S32 wearable_index = gAgentWearables.getWearableCount(type) - 1;
|
|
|
|
// [RLVa:KB] - Checked: 2010-06-09 (RLVa-1.2.0g) | Added: RLVa-1.2.0g
|
|
if ( (rlv_handler_t::isEnabled()) && (gRlvWearableLocks.hasLockedWearable(type)) )
|
|
{
|
|
// We'll use the first wearable we come across that can be removed (moving from top to bottom)
|
|
for (; wearable_index >= 0; wearable_index--)
|
|
{
|
|
const LLViewerWearable* pWearable = gAgentWearables.getViewerWearable(type, wearable_index);
|
|
if (!gRlvWearableLocks.isLockedWearable(pWearable))
|
|
break;
|
|
}
|
|
if (wearable_index < 0)
|
|
return true; // No wearable found that can be removed
|
|
}
|
|
// [/RLVa:KB]
|
|
|
|
LLUUID item_id = gAgentWearables.getWearableItemID(type,wearable_index);
|
|
LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
|
|
}
|
|
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLToolsSelectTool : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string tool_name = userdata.asString();
|
|
if (tool_name == "focus")
|
|
{
|
|
LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(1);
|
|
}
|
|
else if (tool_name == "move")
|
|
{
|
|
LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(2);
|
|
}
|
|
else if (tool_name == "edit")
|
|
{
|
|
LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(3);
|
|
}
|
|
else if (tool_name == "create")
|
|
{
|
|
LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(4);
|
|
}
|
|
else if (tool_name == "land")
|
|
{
|
|
LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(5);
|
|
}
|
|
|
|
// Note: if floater is not visible LLViewerWindow::updateLayout() will
|
|
// attempt to open it, but it won't bring it to front or de-minimize.
|
|
if (gFloaterTools && (gFloaterTools->isMinimized() || !gFloaterTools->isShown() || !gFloaterTools->isFrontmost()))
|
|
{
|
|
gFloaterTools->setMinimized(false);
|
|
gFloaterTools->openFloater();
|
|
gFloaterTools->setVisibleAndFrontmost(true);
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
|
|
/// WINDLIGHT callbacks
|
|
class LLWorldEnvSettings : public view_listener_t
|
|
{
|
|
void defocusEnvFloaters()
|
|
{
|
|
//currently there is only one instance of each floater
|
|
std::vector<std::string> env_floaters_names = { "env_edit_extdaycycle", "env_fixed_environmentent_water", "env_fixed_environmentent_sky" };
|
|
for (std::vector<std::string>::const_iterator it = env_floaters_names.begin(); it != env_floaters_names.end(); ++it)
|
|
{
|
|
LLFloater* env_floater = LLFloaterReg::findTypedInstance<LLFloater>(*it);
|
|
if (env_floater)
|
|
{
|
|
env_floater->setFocus(false);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
// [RLVa:KB] - @setenv
|
|
if (!RlvActions::canChangeEnvironment())
|
|
return true;
|
|
// [/RLVa:KB]
|
|
|
|
std::string event_name = userdata.asString();
|
|
// <FS:Beq> FIRE-29785 fix daytime shortcuts for non-EEP
|
|
#ifdef OPENSIM
|
|
static std::map<std::string, std::string> sky_presets = {
|
|
{"sunrise", "Sunrise"},
|
|
{"noon", "Midday"},
|
|
{"sunset", "Sunset"},
|
|
{"midnight", "Midnight"}
|
|
};
|
|
auto it = sky_presets.find(event_name);
|
|
if( LLGridManager::getInstance()->isInOpenSim() &&
|
|
!LLEnvironment::instance().isExtendedEnvironmentEnabled() &&
|
|
it != sky_presets.end()
|
|
)
|
|
{
|
|
LLSettingsSky::ptr_t legacysky = nullptr;
|
|
LLSD messages;
|
|
legacysky = LLEnvironment::createSkyFromLegacyPreset(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight", "skies", it->second + ".xml"), messages);
|
|
if (legacysky)
|
|
{
|
|
LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, legacysky);
|
|
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
|
|
LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true);
|
|
defocusEnvFloaters();
|
|
}
|
|
else
|
|
{
|
|
LL_WARNS() << "Legacy windlight conversion failed for " << it->second << " existing env unchanged." << LL_ENDL;
|
|
}
|
|
return true;
|
|
}
|
|
#endif
|
|
// </FS:Beq>
|
|
|
|
if (event_name == "sunrise")
|
|
{
|
|
// <FS:Beq> FIRE-29926 - allow manually selected environments to have a user defined transition time.
|
|
//LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNRISE, LLEnvironment::TRANSITION_INSTANT);
|
|
//LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
|
|
LLEnvironment::instance().setManualEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNRISE);
|
|
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
|
|
// </FS:Beq>
|
|
defocusEnvFloaters();
|
|
}
|
|
else if (event_name == "noon")
|
|
{
|
|
// <FS:Beq> FIRE-29926 - allow manually selected environments to have a user defined transition time.
|
|
//LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDDAY, LLEnvironment::TRANSITION_INSTANT);
|
|
//LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
|
|
LLEnvironment::instance().setManualEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDDAY);
|
|
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
|
|
// </FS:Beq>
|
|
defocusEnvFloaters();
|
|
}
|
|
else if (event_name == "legacy noon")
|
|
{
|
|
// <FS:Beq> Add legacy noon to the manually selected environments that can have a user defined transition time.
|
|
// LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY, LLEnvironment::TRANSITION_INSTANT);
|
|
// LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
|
|
LLEnvironment::instance().setManualEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY);
|
|
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
|
|
// </FS:Beq>
|
|
defocusEnvFloaters();
|
|
}
|
|
else if (event_name == "sunset")
|
|
{
|
|
// <FS:Beq> FIRE-29926 - allow manually selected environments to have a user defined transition time.
|
|
//LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET, LLEnvironment::TRANSITION_INSTANT);
|
|
//LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
|
|
LLEnvironment::instance().setManualEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET);
|
|
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); // </FS:Beq>
|
|
defocusEnvFloaters();
|
|
}
|
|
else if (event_name == "midnight")
|
|
{
|
|
// <FS:Beq> FIRE-29926 - allow manually selected environments to have a user defined transition time.
|
|
//LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDNIGHT, LLEnvironment::TRANSITION_INSTANT);
|
|
//LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
|
|
LLEnvironment::instance().setManualEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDNIGHT);
|
|
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL); // </FS:Beq>
|
|
defocusEnvFloaters();
|
|
}
|
|
else if (event_name == "region")
|
|
{
|
|
// reset probe data when reverting back to region sky setting
|
|
gPipeline.mReflectionMapManager.reset();
|
|
|
|
LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL);
|
|
LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
|
|
defocusEnvFloaters();
|
|
}
|
|
else if (event_name == "pause_clouds")
|
|
{
|
|
if (LLEnvironment::instance().isCloudScrollPaused())
|
|
LLEnvironment::instance().resumeCloudScroll();
|
|
else
|
|
LLEnvironment::instance().pauseCloudScroll();
|
|
}
|
|
else if (event_name == "adjust_tool")
|
|
{
|
|
LLFloaterReg::showInstance("env_adjust_snapshot");
|
|
}
|
|
else if (event_name == "my_environs")
|
|
{
|
|
LLFloaterReg::showInstance("my_environments");
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLWorldEnableEnvSettings : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool result = false;
|
|
std::string event_name = userdata.asString();
|
|
|
|
if (event_name == "pause_clouds")
|
|
{
|
|
return LLEnvironment::instance().isCloudScrollPaused();
|
|
}
|
|
|
|
LLSettingsSky::ptr_t sky = LLEnvironment::instance().getEnvironmentFixedSky(LLEnvironment::ENV_LOCAL);
|
|
|
|
if (!sky)
|
|
{
|
|
return (event_name == "region");
|
|
}
|
|
|
|
std::string skyname = (sky) ? sky->getName() : "";
|
|
LLUUID skyid = (sky) ? sky->getAssetId() : LLUUID::null;
|
|
|
|
if (event_name == "sunrise")
|
|
{
|
|
result = (skyid == LLEnvironment::KNOWN_SKY_SUNRISE);
|
|
}
|
|
else if (event_name == "noon")
|
|
{
|
|
result = (skyid == LLEnvironment::KNOWN_SKY_MIDDAY);
|
|
}
|
|
else if (event_name == "legacy noon")
|
|
{
|
|
result = (skyid == LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY);
|
|
}
|
|
else if (event_name == "sunset")
|
|
{
|
|
result = (skyid == LLEnvironment::KNOWN_SKY_SUNSET);
|
|
}
|
|
else if (event_name == "midnight")
|
|
{
|
|
result = (skyid == LLEnvironment::KNOWN_SKY_MIDNIGHT);
|
|
}
|
|
else if (event_name == "region")
|
|
{
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
LL_WARNS() << "Unknown time-of-day item: " << event_name << LL_ENDL;
|
|
}
|
|
return result;
|
|
}
|
|
};
|
|
|
|
class LLWorldEnvPreset : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string item = userdata.asString();
|
|
|
|
if (item == "new_water")
|
|
{
|
|
LLFloaterReg::showInstance("env_fixed_environmentent_water", "new");
|
|
}
|
|
else if (item == "edit_water")
|
|
{
|
|
LLFloaterReg::showInstance("env_fixed_environmentent_water", "edit");
|
|
}
|
|
else if (item == "new_sky")
|
|
{
|
|
LLFloaterReg::showInstance("env_fixed_environmentent_sky", "new");
|
|
}
|
|
else if (item == "edit_sky")
|
|
{
|
|
LLFloaterReg::showInstance("env_fixed_environmentent_sky", "edit");
|
|
}
|
|
else if (item == "new_day_cycle")
|
|
{
|
|
LLFloaterReg::showInstance("env_edit_extdaycycle", LLSDMap("edit_context", "inventory"));
|
|
}
|
|
else if (item == "edit_day_cycle")
|
|
{
|
|
LLFloaterReg::showInstance("env_edit_extdaycycle", LLSDMap("edit_context", "inventory"));
|
|
}
|
|
else
|
|
{
|
|
LL_WARNS() << "Unknown item selected" << LL_ENDL;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLWorldEnableEnvPreset : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
|
|
return false;
|
|
}
|
|
};
|
|
|
|
/// Post-Process callbacks
|
|
class LLWorldPostProcess : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
LLFloaterReg::showInstance("env_post_process");
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class LLWorldCheckBanLines : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
S32 callback_data = userdata.asInteger();
|
|
return gSavedSettings.getS32("ShowBanLines") == callback_data;
|
|
}
|
|
};
|
|
|
|
class LLWorldShowBanLines : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
S32 callback_data = userdata.asInteger();
|
|
gSavedSettings.setS32("ShowBanLines", callback_data);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
void handle_flush_name_caches()
|
|
{
|
|
// <FS:Ansariel> Crash fix
|
|
LLAvatarNameCache::getInstance()->clearCache();
|
|
// </FS:Ansariel>
|
|
if (gCacheName) gCacheName->clear();
|
|
}
|
|
|
|
class LLUploadCostCalculator : public view_listener_t
|
|
{
|
|
std::string mCostStr;
|
|
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::vector<std::string> fields;
|
|
std::string str = userdata.asString();
|
|
boost::split(fields, str, boost::is_any_of(","));
|
|
if (fields.size()<1)
|
|
{
|
|
return false;
|
|
}
|
|
std::string menu_name = fields[0];
|
|
std::string asset_type_str = "texture";
|
|
if (fields.size()>1)
|
|
{
|
|
asset_type_str = fields[1];
|
|
}
|
|
LL_DEBUGS("Benefits") << "userdata " << userdata << " menu_name " << menu_name << " asset_type_str " << asset_type_str << LL_ENDL;
|
|
calculateCost(asset_type_str);
|
|
gMenuHolder->childSetLabelArg(menu_name, "[COST]", mCostStr);
|
|
|
|
return true;
|
|
}
|
|
|
|
void calculateCost(const std::string& asset_type_str);
|
|
|
|
public:
|
|
LLUploadCostCalculator()
|
|
{
|
|
}
|
|
};
|
|
|
|
class LLUpdateMembershipLabel : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
const std::string label_str = LLAgentBenefitsMgr::isCurrent("Base") ? LLTrans::getString("MembershipUpgradeText") : LLTrans::getString("MembershipPremiumText");
|
|
gMenuHolder->childSetLabelArg("Membership", "[Membership]", label_str);
|
|
|
|
// <FS:Ansariel> OpenSim check
|
|
//return true;
|
|
return LLGridManager::instance().isInSecondLife();
|
|
// </FS:Ansariel>
|
|
}
|
|
};
|
|
|
|
|
|
class LLToggleUIHints : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
bool ui_hints_enabled = gSavedSettings.getBOOL("EnableUIHints");
|
|
// toggle
|
|
ui_hints_enabled = !ui_hints_enabled;
|
|
gSavedSettings.setBOOL("EnableUIHints", ui_hints_enabled);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
void LLUploadCostCalculator::calculateCost(const std::string& asset_type_str)
|
|
{
|
|
S32 upload_cost = -1;
|
|
|
|
if (asset_type_str == "texture")
|
|
{
|
|
// This use minimal texture cost to allow bulk and
|
|
// texture upload menu options to be visible
|
|
upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost();
|
|
}
|
|
else if (asset_type_str == "animation")
|
|
{
|
|
upload_cost = LLAgentBenefitsMgr::current().getAnimationUploadCost();
|
|
}
|
|
else if (asset_type_str == "sound")
|
|
{
|
|
upload_cost = LLAgentBenefitsMgr::current().getSoundUploadCost();
|
|
}
|
|
if (upload_cost < 0)
|
|
{
|
|
LL_WARNS() << "Unable to find upload cost for asset_type_str " << asset_type_str << LL_ENDL;
|
|
}
|
|
mCostStr = std::to_string(upload_cost);
|
|
}
|
|
|
|
void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y)
|
|
{
|
|
static LLMenuGL* show_navbar_context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml",
|
|
gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
|
if(gMenuHolder->hasVisibleMenu())
|
|
{
|
|
gMenuHolder->hideMenus();
|
|
}
|
|
show_navbar_context_menu->buildDrawLabels();
|
|
show_navbar_context_menu->updateParent(LLMenuGL::sMenuContainer);
|
|
LLMenuGL::showPopup(ctrl, show_navbar_context_menu, x, y);
|
|
}
|
|
|
|
void show_topinfobar_context_menu(LLView* ctrl, S32 x, S32 y)
|
|
{
|
|
static LLMenuGL* show_topbarinfo_context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_topinfobar.xml",
|
|
gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
|
|
|
|
LLMenuItemGL* landmark_item = show_topbarinfo_context_menu->getChild<LLMenuItemGL>("Landmark");
|
|
if (!LLLandmarkActions::landmarkAlreadyExists())
|
|
{
|
|
landmark_item->setLabel(LLTrans::getString("AddLandmarkNavBarMenu"));
|
|
}
|
|
else
|
|
{
|
|
landmark_item->setLabel(LLTrans::getString("EditLandmarkNavBarMenu"));
|
|
}
|
|
// [RLVa:KB] - Checked: 2012-02-07 (RLVa-1.4.5) | Added: RLVa-1.4.5
|
|
landmark_item->setEnabled(!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC));
|
|
// [/RLVa:KB]
|
|
|
|
if(gMenuHolder->hasVisibleMenu())
|
|
{
|
|
gMenuHolder->hideMenus();
|
|
}
|
|
|
|
show_topbarinfo_context_menu->buildDrawLabels();
|
|
show_topbarinfo_context_menu->updateParent(LLMenuGL::sMenuContainer);
|
|
LLMenuGL::showPopup(ctrl, show_topbarinfo_context_menu, x, y);
|
|
}
|
|
|
|
// <FS:Ansariel> For web browser toolbar button
|
|
void toggleWebBrowser(const LLSD& sdParam)
|
|
{
|
|
if (LLFloaterReg::instanceVisible("web_content"))
|
|
{
|
|
LLFloaterReg::hideInstance("web_content");
|
|
}
|
|
else
|
|
{
|
|
std::string param = sdParam.asString();
|
|
if (param == "HOME_PAGE")
|
|
{
|
|
param = gSavedSettings.getString("FSBrowserHomePage");
|
|
}
|
|
LLWeb::loadURLInternal(param);
|
|
}
|
|
}
|
|
// </FS:Ansariel> For web browser toolbar button
|
|
|
|
// <FS:Ansariel> Toggle debug settings floater
|
|
void toggleSettingsDebug()
|
|
{
|
|
LLFloaterReg::toggleInstance("settings_debug", "all");
|
|
}
|
|
// </FS:Ansariel> Toggle debug settings floater
|
|
|
|
// <FS:Ansariel> Toggle teleport history panel directly
|
|
void toggleTeleportHistory()
|
|
{
|
|
if (gSavedSettings.getBOOL("FSUseStandaloneTeleportHistoryFloater"))
|
|
{
|
|
LLFloaterReg::toggleInstance("fs_teleporthistory");
|
|
}
|
|
else
|
|
{
|
|
LLFloater* floater = LLFloaterReg::findInstance("places");
|
|
if (floater && floater->isMinimized())
|
|
{
|
|
floater->setMinimized(false);
|
|
}
|
|
else if (LLFloater::isShown(floater))
|
|
{
|
|
LLFloaterReg::hideInstance("places");
|
|
}
|
|
else
|
|
{
|
|
LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "open_teleport_history_tab"));
|
|
}
|
|
}
|
|
}
|
|
// </FS:Ansariel> Toggle teleport history panel directly
|
|
|
|
// <FS:Techwolf Lupindo> export
|
|
bool enable_export_object()
|
|
{
|
|
for (LLObjectSelection::root_iterator iter = LLSelectMgr::getInstance()->getSelection()->root_begin();
|
|
iter != LLSelectMgr::getInstance()->getSelection()->root_end(); iter++)
|
|
{
|
|
LLSelectNode* node = *iter;
|
|
LLViewerObject* obj = node->getObject();
|
|
if (obj || node)
|
|
{
|
|
return gSavedSettings.getBOOL("FSEnableObjectExports");
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
class FSObjectExport : public view_listener_t
|
|
{
|
|
bool handleEvent( const LLSD& userdata)
|
|
{
|
|
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (objectp)
|
|
{
|
|
LLFloaterReg::showInstance("fs_export");
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:Techwolf Lupindo>
|
|
|
|
// <FS:CR>
|
|
class FSObjectExportCollada : public view_listener_t
|
|
{
|
|
bool handleEvent( const LLSD& userdata)
|
|
{
|
|
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
|
if (objectp)
|
|
{
|
|
LLFloaterReg::showInstance("export_collada");
|
|
}
|
|
return true;
|
|
}
|
|
};
|
|
// </FS:CR>
|
|
|
|
// <FS:Zi> Make sure to call this before any of the UI is set up, so all text editors can
|
|
// pick up the menu properly.
|
|
void initialize_edit_menu()
|
|
{
|
|
view_listener_t::addMenu(new LLEditUndo(), "Edit.Undo");
|
|
view_listener_t::addMenu(new LLEditRedo(), "Edit.Redo");
|
|
view_listener_t::addMenu(new LLEditCut(), "Edit.Cut");
|
|
view_listener_t::addMenu(new LLEditCopy(), "Edit.Copy");
|
|
view_listener_t::addMenu(new LLEditPaste(), "Edit.Paste");
|
|
view_listener_t::addMenu(new LLEditDelete(), "Edit.Delete");
|
|
view_listener_t::addMenu(new LLEditSelectAll(), "Edit.SelectAll");
|
|
view_listener_t::addMenu(new LLEditDeselect(), "Edit.Deselect");
|
|
view_listener_t::addMenu(new LLEditTakeOff(), "Edit.TakeOff");
|
|
view_listener_t::addMenu(new LLEditEnableUndo(), "Edit.EnableUndo");
|
|
view_listener_t::addMenu(new LLEditEnableRedo(), "Edit.EnableRedo");
|
|
view_listener_t::addMenu(new LLEditEnableCut(), "Edit.EnableCut");
|
|
view_listener_t::addMenu(new LLEditEnableCopy(), "Edit.EnableCopy");
|
|
view_listener_t::addMenu(new LLEditEnablePaste(), "Edit.EnablePaste");
|
|
view_listener_t::addMenu(new LLEditEnableDelete(), "Edit.EnableDelete");
|
|
view_listener_t::addMenu(new LLEditEnableSelectAll(), "Edit.EnableSelectAll");
|
|
view_listener_t::addMenu(new LLEditEnableDeselect(), "Edit.EnableDeselect");
|
|
|
|
}
|
|
|
|
void initialize_spellcheck_menu()
|
|
{
|
|
LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
|
|
LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar();
|
|
|
|
commit.add("SpellCheck.ReplaceWithSuggestion", boost::bind(&handle_spellcheck_replace_with_suggestion, _1, _2));
|
|
enable.add("SpellCheck.VisibleSuggestion", boost::bind(&visible_spellcheck_suggestion, _1, _2));
|
|
commit.add("SpellCheck.AddToDictionary", boost::bind(&handle_spellcheck_add_to_dictionary, _1));
|
|
enable.add("SpellCheck.EnableAddToDictionary", boost::bind(&enable_spellcheck_add_to_dictionary, _1));
|
|
commit.add("SpellCheck.AddToIgnore", boost::bind(&handle_spellcheck_add_to_ignore, _1));
|
|
enable.add("SpellCheck.EnableAddToIgnore", boost::bind(&enable_spellcheck_add_to_ignore, _1));
|
|
}
|
|
|
|
//<FS:KC> Centralize a some of these volume panel callbacks
|
|
static void volume_controls_open_volume_prefs()
|
|
{
|
|
// bring up the prefs floater
|
|
LLFloaterPreference* prefsfloater = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
|
|
if (prefsfloater)
|
|
{
|
|
// grab the 'audio' panel from the preferences floater and bring it the front!
|
|
prefsfloater->selectPanel("audio");
|
|
}
|
|
}
|
|
|
|
void volume_controls_on_click_set_sounds(const LLUICtrl* ctrl)
|
|
{
|
|
const LLPanel* volume_control_panel = dynamic_cast<const LLPanel*>(ctrl->getParent());
|
|
if (volume_control_panel)
|
|
{
|
|
// Disable Enable gesture/collisions sounds checkbox if the master sound is disabled
|
|
// or if sound effects are disabled.
|
|
|
|
// <FS:PP> FIRE-9856: Mute sound effects disable plays sound from collisions and plays sound from gestures checkbox not disable after restart/relog
|
|
// volume_control_panel->getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds"));
|
|
// volume_control_panel->getChild<LLCheckBoxCtrl>("collisions_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds"));
|
|
bool mute_sound_effects = gSavedSettings.getBOOL("MuteSounds");
|
|
bool mute_all_sounds = gSavedSettings.getBOOL("MuteAudio");
|
|
volume_control_panel->getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!(mute_sound_effects || mute_all_sounds));
|
|
volume_control_panel->getChild<LLCheckBoxCtrl>("collisions_audio_play_btn")->setEnabled(!(mute_sound_effects || mute_all_sounds));
|
|
// </FS:PP>
|
|
|
|
}
|
|
}
|
|
|
|
void volume_controls_set_control_false(const LLUICtrl* ctrl, const LLSD& user_data)
|
|
{
|
|
LLPanel* volume_control_panel = dynamic_cast<LLPanel*>(ctrl->getParent());
|
|
if (volume_control_panel)
|
|
{
|
|
std::string control_name = user_data.asString();
|
|
LLControlVariable* control = volume_control_panel->findControl(control_name);
|
|
|
|
if (control)
|
|
control->set(LLSD(false));
|
|
}
|
|
}
|
|
|
|
void initialize_volume_controls_callbacks()
|
|
{
|
|
LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
|
|
commit.add("MediaListCtrl.GoMediaPrefs", boost::bind(&volume_controls_open_volume_prefs));
|
|
commit.add("Pref.SetSounds", boost::bind(&volume_controls_on_click_set_sounds, _1));
|
|
commit.add("Pref.setControlFalse", boost::bind(&volume_controls_set_control_false, _1, _2));
|
|
}
|
|
//</FS:KC>
|
|
|
|
// <FS:Ansariel> Force HTTP features on SL
|
|
bool use_http_inventory()
|
|
{
|
|
#ifdef OPENSIM
|
|
return (LLGridManager::getInstance()->isInSecondLife() || gSavedSettings.getBOOL("UseHTTPInventory"));
|
|
#else
|
|
return true;
|
|
#endif
|
|
}
|
|
|
|
bool use_http_textures()
|
|
{
|
|
#ifdef OPENSIM
|
|
static LLCachedControl<bool> use_http(gSavedSettings, "ImagePipelineUseHTTP", true);
|
|
return (LLGridManager::getInstance()->isInSecondLife() || use_http);
|
|
#else
|
|
return true;
|
|
#endif
|
|
}
|
|
// <FS:Ansariel>
|
|
|
|
// <FS:Ansariel> Optional small camera floater
|
|
class FSToggleCameraFloater : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string floater_name = gSavedSettings.getBOOL("FSUseSmallCameraFloater") ? "fs_camera_small" : "camera";
|
|
LLFloaterReg::toggleInstance(floater_name);
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class FSCheckCameraFloater : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
static LLCachedControl<bool> fsUseSmallCameraFloater(gSavedSettings, "FSUseSmallCameraFloater");
|
|
return LLFloaterReg::instanceVisible(fsUseSmallCameraFloater ? "fs_camera_small" : "camera");
|
|
}
|
|
};
|
|
// <FS:Ansariel>
|
|
|
|
// <FS:Ansariel> Add avater complexity sttings to menu
|
|
class FSRenderAvatarComplexityMode : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string param = userdata.asString();
|
|
if (param == "everyone")
|
|
{
|
|
gSavedSettings.setS32("RenderAvatarComplexityMode", 0);
|
|
}
|
|
else if (param == "always_friends")
|
|
{
|
|
gSavedSettings.setS32("RenderAvatarComplexityMode", 1);
|
|
}
|
|
else if (param == "only_friends")
|
|
{
|
|
gSavedSettings.setS32("RenderAvatarComplexityMode", 2);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
|
|
class FSCheckRenderAvatarComplexityMode : public view_listener_t
|
|
{
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
std::string param = userdata.asString();
|
|
if (param == "everyone")
|
|
{
|
|
return gSavedSettings.getS32("RenderAvatarComplexityMode") == 0;
|
|
}
|
|
else if (param == "always_friends")
|
|
{
|
|
return gSavedSettings.getS32("RenderAvatarComplexityMode") == 1;
|
|
}
|
|
else if (param == "only_friends")
|
|
{
|
|
return gSavedSettings.getS32("RenderAvatarComplexityMode") == 2;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
};
|
|
// <FS:Ansariel>
|
|
|
|
void initialize_menus()
|
|
{
|
|
// A parameterized event handler used as ctrl-8/9/0 zoom controls below.
|
|
class LLZoomer : public view_listener_t
|
|
{
|
|
public:
|
|
// The "mult" parameter says whether "val" is a multiplier or used to set the value.
|
|
LLZoomer(F32 val, bool mult=true) : mVal(val), mMult(mult) {}
|
|
bool handleEvent(const LLSD& userdata)
|
|
{
|
|
F32 new_fov_rad = mMult ? LLViewerCamera::getInstance()->getDefaultFOV() * mVal : mVal;
|
|
LLViewerCamera::getInstance()->setDefaultFOV(new_fov_rad);
|
|
gSavedSettings.setF32("CameraAngle", LLViewerCamera::getInstance()->getView()); // setView may have clamped it.
|
|
return true;
|
|
}
|
|
private:
|
|
F32 mVal;
|
|
bool mMult;
|
|
};
|
|
|
|
LLUICtrl::EnableCallbackRegistry::Registrar& enable = LLUICtrl::EnableCallbackRegistry::currentRegistrar();
|
|
LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
|
|
|
|
// Generic enable and visible
|
|
// Don't prepend MenuName.Foo because these can be used in any menu.
|
|
enable.add("IsGodCustomerService", boost::bind(&is_god_customer_service));
|
|
|
|
enable.add("displayViewerEventRecorderMenuItems",boost::bind(&LLViewerEventRecorder::displayViewerEventRecorderMenuItems,&LLViewerEventRecorder::instance()));
|
|
|
|
view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts");
|
|
|
|
view_listener_t::addEnable(new LLUpdateMembershipLabel(), "Membership.UpdateLabel");
|
|
|
|
// <FS:Ansariel> [FS communication UI]
|
|
//enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed));
|
|
// <FS:minerjr> [FIRE-35039] Add flag to show/hide the on-screen console
|
|
// Add menu view listener to controll the FSShowOnscreenConsole value
|
|
view_listener_t::addMenu(new LLCommCheckShowOnscreenConsole(), "Comm.CheckShowOnscreenConsole"); // Add menu listener for "Show On-screen Console" check class
|
|
view_listener_t::addMenu(new LLCommSetShowOnscreenConsole(), "Comm.SetShowOnscreenConsole"); // Add menu listener for "Show On-screen Console" set class
|
|
// </FS:minerjr> [FIRE-35039]
|
|
|
|
enable.add("GridCheck", boost::bind(&checkIsGrid, _2)); // <FS:CR> Opensim menu item visibility control
|
|
enable.add("GridFeatureCheck", boost::bind(&isGridFeatureEnabled, _2));
|
|
commit.add("OpenGridStatus", boost::bind(&openGridStatus)); // <FS:Ansariel> FIRE-21236 - Help Menu - Check Grid Status doesn't open using External Browser
|
|
|
|
// Agent
|
|
commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying));
|
|
enable.add("Agent.enableFlyLand", boost::bind(&enable_fly_land));
|
|
enable.add("Agent.enableFlying", boost::bind(&LLAgent::enableFlying)); // <FS:Ansariel> Keep this
|
|
commit.add("Agent.PressMicrophone", boost::bind(&LLAgent::pressMicrophone, _2));
|
|
commit.add("Agent.ReleaseMicrophone", boost::bind(&LLAgent::releaseMicrophone, _2));
|
|
commit.add("Agent.ToggleMicrophone", boost::bind(&LLAgent::toggleMicrophone, _2));
|
|
enable.add("Agent.IsMicrophoneOn", boost::bind(&LLAgent::isMicrophoneOn, _2));
|
|
enable.add("Agent.IsActionAllowed", boost::bind(&LLAgent::isActionAllowed, _2));
|
|
|
|
// File menu
|
|
init_menu_file();
|
|
|
|
view_listener_t::addMenu(new LLEditEnableTakeOff(), "Edit.EnableTakeOff");
|
|
view_listener_t::addMenu(new LLEditEnableCustomizeAvatar(), "Edit.EnableCustomizeAvatar");
|
|
view_listener_t::addMenu(new LLEnableEditShape(), "Edit.EnableEditShape");
|
|
view_listener_t::addMenu(new LLEnableHoverHeight(), "Edit.EnableHoverHeight");
|
|
view_listener_t::addMenu(new LLEnableEditPhysics(), "Edit.EnableEditPhysics");
|
|
commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar));
|
|
commit.add("NowWearing", boost::bind(&handle_now_wearing));
|
|
commit.add("EditOutfit", boost::bind(&handle_edit_outfit));
|
|
commit.add("EditShape", boost::bind(&handle_edit_shape));
|
|
commit.add("HoverHeight", boost::bind(&handle_hover_height));
|
|
commit.add("EditPhysics", boost::bind(&handle_edit_physics));
|
|
// <FS:TT> Client LSL Bridge
|
|
commit.add("RecreateLSLBridge", boost::bind(&handle_recreate_lsl_bridge));
|
|
// </FS:TT>
|
|
|
|
// View menu
|
|
view_listener_t::addMenu(new LLViewMouselook(), "View.Mouselook");
|
|
view_listener_t::addMenu(new LLViewJoystickFlycam(), "View.JoystickFlycam");
|
|
view_listener_t::addMenu(new LLViewResetView(), "View.ResetView");
|
|
view_listener_t::addMenu(new LLViewLookAtLastChatter(), "View.LookAtLastChatter");
|
|
view_listener_t::addMenu(new LLViewShowHoverTips(), "View.ShowHoverTips");
|
|
view_listener_t::addMenu(new LLViewHighlightTransparent(), "View.HighlightTransparent");
|
|
view_listener_t::addMenu(new LLViewHighlightTransparentRigged(), "View.HighlightTransparentRigged"); // <FS:Beq/> FIRE-32132 et al. Allow rigged mesh transparency highlights to be toggled
|
|
view_listener_t::addMenu(new LLViewToggleRenderType(), "View.ToggleRenderType");
|
|
view_listener_t::addMenu(new LLViewShowHUDAttachments(), "View.ShowHUDAttachments");
|
|
view_listener_t::addMenu(new LLZoomer(1.2f), "View.ZoomOut");
|
|
view_listener_t::addMenu(new LLZoomer(1/1.2f), "View.ZoomIn");
|
|
view_listener_t::addMenu(new LLZoomer(DEFAULT_FIELD_OF_VIEW, false), "View.ZoomDefault");
|
|
view_listener_t::addMenu(new LLViewDefaultUISize(), "View.DefaultUISize");
|
|
view_listener_t::addMenu(new LLViewToggleUI(), "View.ToggleUI");
|
|
view_listener_t::addMenu(new LLViewCheckToggleUI(), "View.CheckToggleUI"); // <FS:Ansariel> Notification not showing if hiding the UI
|
|
|
|
view_listener_t::addMenu(new LLViewEnableMouselook(), "View.EnableMouselook");
|
|
view_listener_t::addMenu(new LLViewEnableJoystickFlycam(), "View.EnableJoystickFlycam");
|
|
view_listener_t::addMenu(new LLViewEnableLastChatter(), "View.EnableLastChatter");
|
|
|
|
view_listener_t::addMenu(new LLViewCheckJoystickFlycam(), "View.CheckJoystickFlycam");
|
|
view_listener_t::addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips");
|
|
view_listener_t::addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent");
|
|
view_listener_t::addMenu(new LLViewCheckHighlightTransparentRigged(), "View.CheckHighlightTransparentRigged");// <FS:Beq/> FIRE-32132 et al. Allow rigged mesh transparency highlights to be toggled
|
|
view_listener_t::addMenu(new LLViewCheckRenderType(), "View.CheckRenderType");
|
|
view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway");
|
|
view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb");
|
|
view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments");
|
|
enable.add("View.EnableHUDAttachments", boost::bind(&enable_show_HUD_attachments)); // <FS:Ansariel> Disable Show HUD attachments if prevented by RLVa
|
|
// <FS:Zi> Add reset camera angles menu
|
|
view_listener_t::addMenu(new LLViewResetCameraAngles(), "View.ResetCameraAngles");
|
|
// </FS:Zi>
|
|
// <FS:Ansariel> Optional small camera floater
|
|
view_listener_t::addMenu(new FSToggleCameraFloater(), "View.ToggleCameraFloater");
|
|
view_listener_t::addMenu(new FSCheckCameraFloater(), "View.CheckCameraFloater");
|
|
// </FS:Ansariel>
|
|
|
|
// <FS:Ansariel> Keep this for menu check item
|
|
// Me > Movement
|
|
view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying");
|
|
//Communicate Nearby chat
|
|
// <FS:Ansariel> [FS Communication UI]
|
|
//view_listener_t::addMenu(new LLCommunicateNearbyChat(), "Communicate.NearbyChat");
|
|
|
|
// World menu
|
|
view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
|
|
view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark");
|
|
view_listener_t::addMenu(new LLWorldPlaceProfile(), "World.PlaceProfile");
|
|
view_listener_t::addMenu(new LLWorldSetHomeLocation(), "World.SetHomeLocation");
|
|
view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome");
|
|
view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway");
|
|
view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb");
|
|
view_listener_t::addMenu(new LLWorldLindenHome(), "World.LindenHome");
|
|
|
|
view_listener_t::addMenu(new LLWorldGetAway(), "World.GetAway"); //[SJ FIRE-2177]
|
|
view_listener_t::addMenu(new LLWorldGetBusy(), "World.GetBusy"); //[SJ FIRE-2177]
|
|
view_listener_t::addMenu(new LLWorldSetAutorespond(), "World.SetAutorespond");
|
|
view_listener_t::addMenu(new LLWorldGetAutorespond(), "World.GetAutorespond"); //[SJ FIRE-2177]
|
|
// <FS:PP> FIRE-1245: Option to block/reject teleport requests
|
|
view_listener_t::addMenu(new LLWorldSetRejectTeleportOffers(), "World.SetRejectTeleportOffers");
|
|
view_listener_t::addMenu(new LLWorldGetRejectTeleportOffers(), "World.GetRejectTeleportOffers");
|
|
// </FS:PP>
|
|
// <FS:PP> FIRE-15233: Automatic friendship request refusal
|
|
view_listener_t::addMenu(new LLWorldSetRejectFriendshipRequests(), "World.SetRejectFriendshipRequests");
|
|
view_listener_t::addMenu(new LLWorldGetRejectFriendshipRequests(), "World.GetRejectFriendshipRequests");
|
|
// </FS:PP>
|
|
// <FS:PP> FIRE-1245: Option to block/reject teleport requests
|
|
view_listener_t::addMenu(new LLWorldSetRejectAllGroupInvites(), "World.SetRejectAllGroupInvites");
|
|
view_listener_t::addMenu(new LLWorldGetRejectAllGroupInvites(), "World.GetRejectAllGroupInvites");
|
|
// </FS:PP>
|
|
view_listener_t::addMenu(new LLWorldSetAutorespondNonFriends(), "World.SetAutorespondNonFriends");
|
|
view_listener_t::addMenu(new LLWorldGetAutorespondNonFriends(), "World.GetAutorespondNonFriends"); //[SJ FIRE-2177]
|
|
view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark");
|
|
// [RLVa:KB]
|
|
enable.add("World.EnablePlaceProfile", boost::bind(&enable_place_profile));
|
|
// [/RLVa:KB]
|
|
view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation");
|
|
view_listener_t::addMenu(new LLWorldEnableTeleportHome(), "World.EnableTeleportHome");
|
|
view_listener_t::addMenu(new LLWorldEnableBuyLand(), "World.EnableBuyLand");
|
|
|
|
view_listener_t::addMenu(new LLWorldCheckAlwaysRun(), "World.CheckAlwaysRun");
|
|
|
|
view_listener_t::addMenu(new LLWorldEnvSettings(), "World.EnvSettings");
|
|
view_listener_t::addMenu(new LLWorldEnableEnvSettings(), "World.EnableEnvSettings");
|
|
view_listener_t::addMenu(new LLWorldEnvPreset(), "World.EnvPreset");
|
|
view_listener_t::addMenu(new LLWorldEnableEnvPreset(), "World.EnableEnvPreset");
|
|
view_listener_t::addMenu(new LLWorldPostProcess(), "World.PostProcess");
|
|
view_listener_t::addMenu(new LLWorldCheckBanLines() , "World.CheckBanLines");
|
|
view_listener_t::addMenu(new LLWorldShowBanLines() , "World.ShowBanLines");
|
|
|
|
// Tools menu
|
|
view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool");
|
|
view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects");
|
|
view_listener_t::addMenu(new LLToolsSelectOnlyMovableObjects(), "Tools.SelectOnlyMovableObjects");
|
|
view_listener_t::addMenu(new LLToolsSelectInvisibleObjects(), "Tools.SelectInvisibleObjects");
|
|
view_listener_t::addMenu(new LLToolsSelectReflectionProbes(), "Tools.SelectReflectionProbes");
|
|
view_listener_t::addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding");
|
|
view_listener_t::addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection");
|
|
view_listener_t::addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius");
|
|
view_listener_t::addMenu(new LLToolsEditLinkedParts(), "Tools.EditLinkedParts");
|
|
view_listener_t::addMenu(new LLToolsSnapObjectXY(), "Tools.SnapObjectXY");
|
|
view_listener_t::addMenu(new LLToolsUseSelectionForGrid(), "Tools.UseSelectionForGrid");
|
|
view_listener_t::addMenu(new LLToolsSelectNextPartFace(), "Tools.SelectNextPart");
|
|
commit.add("Tools.Link", boost::bind(&handle_link_objects));
|
|
commit.add("Tools.Unlink", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
|
|
view_listener_t::addMenu(new LLToolsStopAllAnimations(), "Tools.StopAllAnimations");
|
|
view_listener_t::addMenu(new LLToolsReleaseKeys(), "Tools.ReleaseKeys");
|
|
view_listener_t::addMenu(new LLToolsEnableReleaseKeys(), "Tools.EnableReleaseKeys");
|
|
commit.add("Tools.LookAtSelection", boost::bind(&handle_look_at_selection, _2));
|
|
commit.add("Tools.ScriptInfo",boost::bind(&handle_script_info));
|
|
commit.add("Tools.BuyOrTake", boost::bind(&handle_buy_or_take));
|
|
commit.add("Tools.TakeCopy", boost::bind(&handle_take_copy));
|
|
view_listener_t::addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory");
|
|
view_listener_t::addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction");
|
|
view_listener_t::addMenu(new FSToolsResyncAnimations(), "Tools.ResyncAnimations"); // <FS:CR> Resync Animations
|
|
view_listener_t::addMenu(new FSToolsUndeform(), "Tools.Undeform"); // <FS:CR> FIRE-4345: Undeform
|
|
view_listener_t::addMenu(new FSDerenderAnimatedObjects(), "Tools.DerenderAnimatedObjects"); // <FS:Beq> Animesh Kill switch
|
|
|
|
view_listener_t::addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie");
|
|
view_listener_t::addMenu(new LLToolsEnableSelectNextPart(), "Tools.EnableSelectNextPart");
|
|
enable.add("Tools.EnableLink", boost::bind(&LLSelectMgr::enableLinkObjects, LLSelectMgr::getInstance()));
|
|
enable.add("Tools.EnableUnlink", boost::bind(&LLSelectMgr::enableUnlinkObjects, LLSelectMgr::getInstance()));
|
|
view_listener_t::addMenu(new LLToolsEnableBuyOrTake(), "Tools.EnableBuyOrTake");
|
|
enable.add("Tools.EnableTakeCopy", boost::bind(&enable_object_take_copy));
|
|
enable.add("Tools.EnableCopySeparate", boost::bind(&enable_take_copy_objects));
|
|
enable.add("Tools.VisibleBuyObject", boost::bind(&tools_visible_buy_object));
|
|
enable.add("Tools.VisibleTakeObject", boost::bind(&tools_visible_take_object));
|
|
view_listener_t::addMenu(new LLToolsEnableSaveToObjectInventory(), "Tools.EnableSaveToObjectInventory");
|
|
|
|
view_listener_t::addMenu(new LLToolsEnablePathfinding(), "Tools.EnablePathfinding");
|
|
view_listener_t::addMenu(new LLToolsEnablePathfindingView(), "Tools.EnablePathfindingView");
|
|
view_listener_t::addMenu(new LLToolsDoPathfindingRebakeRegion(), "Tools.DoPathfindingRebakeRegion");
|
|
view_listener_t::addMenu(new LLToolsEnablePathfindingRebakeRegion(), "Tools.EnablePathfindingRebakeRegion");
|
|
|
|
// Help menu
|
|
// most items use the ShowFloater method
|
|
view_listener_t::addMenu(new LLToggleHowTo(), "Help.ToggleHowTo");
|
|
|
|
// Advanced menu
|
|
view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole");
|
|
view_listener_t::addMenu(new LLAdvancedCheckConsole(), "Advanced.CheckConsole");
|
|
view_listener_t::addMenu(new LLAdvancedDumpInfoToConsole(), "Advanced.DumpInfoToConsole");
|
|
|
|
// Advanced > HUD Info
|
|
view_listener_t::addMenu(new LLAdvancedToggleHUDInfo(), "Advanced.ToggleHUDInfo");
|
|
view_listener_t::addMenu(new LLAdvancedCheckHUDInfo(), "Advanced.CheckHUDInfo");
|
|
|
|
// Advanced Other Settings
|
|
view_listener_t::addMenu(new LLAdvancedClearGroupCache(), "Advanced.ClearGroupCache");
|
|
|
|
// Advanced > Render > Types
|
|
view_listener_t::addMenu(new LLAdvancedToggleRenderType(), "Advanced.ToggleRenderType");
|
|
view_listener_t::addMenu(new LLAdvancedCheckRenderType(), "Advanced.CheckRenderType");
|
|
|
|
//// Advanced > Render > Features
|
|
view_listener_t::addMenu(new LLAdvancedToggleFeature(), "Advanced.ToggleFeature");
|
|
view_listener_t::addMenu(new LLAdvancedCheckFeature(), "Advanced.CheckFeature");
|
|
|
|
view_listener_t::addMenu(new LLAdvancedCheckDisplayTextureDensity(), "Advanced.CheckDisplayTextureDensity");
|
|
view_listener_t::addMenu(new LLAdvancedSetDisplayTextureDensity(), "Advanced.SetDisplayTextureDensity");
|
|
|
|
// Advanced > Render > Info Displays
|
|
view_listener_t::addMenu(new LLAdvancedToggleInfoDisplay(), "Advanced.ToggleInfoDisplay");
|
|
view_listener_t::addMenu(new LLAdvancedCheckInfoDisplay(), "Advanced.CheckInfoDisplay");
|
|
view_listener_t::addMenu(new LLAdvancedSelectedTextureInfo(), "Advanced.SelectedTextureInfo");
|
|
commit.add("Advanced.SelectedMaterialInfo", boost::bind(&handle_selected_material_info));
|
|
view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe");
|
|
view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe");
|
|
// Develop > Render
|
|
view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate");
|
|
view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate");
|
|
view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame");
|
|
view_listener_t::addMenu(new LLAdvancedCheckPeriodicSlowFrame(), "Advanced.CheckPeriodicSlowFrame");
|
|
view_listener_t::addMenu(new LLAdvancedHandleAttachedLightParticles(), "Advanced.HandleAttachedLightParticles");
|
|
view_listener_t::addMenu(new LLAdvancedCheckRenderShadowOption(), "Advanced.CheckRenderShadowOption");
|
|
view_listener_t::addMenu(new LLAdvancedClickRenderShadowOption(), "Advanced.ClickRenderShadowOption");
|
|
view_listener_t::addMenu(new LLAdvancedClickRenderProfile(), "Advanced.ClickRenderProfile");
|
|
view_listener_t::addMenu(new LLAdvancedClickRenderBenchmark(), "Advanced.ClickRenderBenchmark");
|
|
view_listener_t::addMenu(new LLAdvancedClickHDRIPreview(), "Advanced.ClickHDRIPreview");
|
|
view_listener_t::addMenu(new LLAdvancedClickGLTFOpen(), "Advanced.ClickGLTFOpen");
|
|
view_listener_t::addMenu(new LLAdvancedClickGLTFSaveAs(), "Advanced.ClickGLTFSaveAs");
|
|
view_listener_t::addMenu(new LLAdvancedClickGLTFUpload(), "Advanced.ClickGLTFUpload");
|
|
view_listener_t::addMenu(new LLAdvancedClickGLTFEdit(), "Advanced.ClickGLTFEdit");
|
|
view_listener_t::addMenu(new LLAdvancedClickResizeWindow(), "Advanced.ClickResizeWindow");
|
|
view_listener_t::addMenu(new LLAdvancedPurgeShaderCache(), "Advanced.ClearShaderCache");
|
|
//[FIX FIRE-1927 - enable DoubleClickTeleport shortcut : SJ]
|
|
view_listener_t::addMenu(new FSAdvancedToggleDoubleClickAction, "Advanced.SetDoubleClickAction");
|
|
view_listener_t::addMenu(new FSAdvancedCheckEnabledDoubleClickAction, "Advanced.CheckEnabledDoubleClickAction");
|
|
|
|
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
|
|
view_listener_t::addMenu(new LLAdvancedHandleToggleHackedGodmode(), "Advanced.HandleToggleHackedGodmode");
|
|
view_listener_t::addMenu(new LLAdvancedCheckToggleHackedGodmode(), "Advanced.CheckToggleHackedGodmode");
|
|
view_listener_t::addMenu(new LLAdvancedEnableToggleHackedGodmode(), "Advanced.EnableToggleHackedGodmode");
|
|
#endif
|
|
|
|
// Advanced > World
|
|
view_listener_t::addMenu(new LLAdvancedDumpScriptedCamera(), "Advanced.DumpScriptedCamera");
|
|
view_listener_t::addMenu(new LLAdvancedDumpRegionObjectCache(), "Advanced.DumpRegionObjectCache");
|
|
view_listener_t::addMenu(new LLAdvancedToggleStatsRecorder(), "Advanced.ToggleStatsRecorder");
|
|
view_listener_t::addMenu(new LLAdvancedCheckStatsRecorder(), "Advanced.CheckStatsRecorder");
|
|
view_listener_t::addMenu(new LLAdvancedToggleInterestList360Mode(), "Advanced.ToggleInterestList360Mode");
|
|
view_listener_t::addMenu(new LLAdvancedCheckInterestList360Mode(), "Advanced.CheckInterestList360Mode");
|
|
view_listener_t::addMenu(new LLAdvancedResetInterestLists(), "Advanced.ResetInterestLists");
|
|
|
|
// Develop > Terrain
|
|
view_listener_t::addMenu(new LLAdvancedRebuildTerrain(), "Advanced.RebuildTerrain");
|
|
view_listener_t::addMenu(new LLAdvancedTerrainCreateLocalPaintMap(), "Advanced.TerrainCreateLocalPaintMap");
|
|
view_listener_t::addMenu(new LLAdvancedTerrainDeleteLocalPaintMap(), "Advanced.TerrainDeleteLocalPaintMap");
|
|
|
|
// Advanced > UI
|
|
commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2)); // sigh! this one opens the MEDIA browser
|
|
commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2)); // this one opens the Web Content floater
|
|
commit.add("Advanced.ShowURL", boost::bind(&handle_show_url, _2));
|
|
commit.add("Advanced.ReportBug", boost::bind(&handle_report_bug, _2));
|
|
view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");
|
|
view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");
|
|
view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory");
|
|
commit.add("Advanced.DumpTimers", boost::bind(&handle_dump_timers) );
|
|
commit.add("Advanced.DumpFocusHolder", boost::bind(&handle_dump_focus) );
|
|
view_listener_t::addMenu(new LLAdvancedPrintSelectedObjectInfo(), "Advanced.PrintSelectedObjectInfo");
|
|
view_listener_t::addMenu(new LLAdvancedPrintAgentInfo(), "Advanced.PrintAgentInfo");
|
|
view_listener_t::addMenu(new LLAdvancedToggleDebugClicks(), "Advanced.ToggleDebugClicks");
|
|
view_listener_t::addMenu(new LLAdvancedCheckDebugClicks(), "Advanced.CheckDebugClicks");
|
|
view_listener_t::addMenu(new LLAdvancedCheckDebugViews(), "Advanced.CheckDebugViews");
|
|
view_listener_t::addMenu(new LLAdvancedToggleDebugViews(), "Advanced.ToggleDebugViews");
|
|
view_listener_t::addMenu(new LLAdvancedCheckDebugUnicode(), "Advanced.CheckDebugUnicode");
|
|
view_listener_t::addMenu(new LLAdvancedToggleDebugUnicode(), "Advanced.ToggleDebugUnicode");
|
|
view_listener_t::addMenu(new LLAdvancedCheckDebugCamera(), "Advanced.CheckDebugCamera");
|
|
view_listener_t::addMenu(new LLAdvancedToggleDebugCamera(), "Advanced.ToggleDebugCamera");
|
|
view_listener_t::addMenu(new LLAdvancedToggleXUINameTooltips(), "Advanced.ToggleXUINameTooltips");
|
|
view_listener_t::addMenu(new LLAdvancedCheckXUINameTooltips(), "Advanced.CheckXUINameTooltips");
|
|
view_listener_t::addMenu(new LLAdvancedToggleDebugMouseEvents(), "Advanced.ToggleDebugMouseEvents");
|
|
view_listener_t::addMenu(new LLAdvancedCheckDebugMouseEvents(), "Advanced.CheckDebugMouseEvents");
|
|
view_listener_t::addMenu(new LLAdvancedToggleDebugKeys(), "Advanced.ToggleDebugKeys");
|
|
view_listener_t::addMenu(new LLAdvancedCheckDebugKeys(), "Advanced.CheckDebugKeys");
|
|
view_listener_t::addMenu(new LLAdvancedToggleDebugWindowProc(), "Advanced.ToggleDebugWindowProc");
|
|
view_listener_t::addMenu(new LLAdvancedCheckDebugWindowProc(), "Advanced.CheckDebugWindowProc");
|
|
|
|
// Advanced > XUI
|
|
commit.add("Advanced.ReloadColorSettings", boost::bind(&LLUIColorTable::loadFromSettings, LLUIColorTable::getInstance()));
|
|
view_listener_t::addMenu(new LLAdvancedLoadUIFromXML(), "Advanced.LoadUIFromXML");
|
|
view_listener_t::addMenu(new LLAdvancedSaveUIToXML(), "Advanced.SaveUIToXML");
|
|
view_listener_t::addMenu(new LLAdvancedToggleXUINames(), "Advanced.ToggleXUINames");
|
|
view_listener_t::addMenu(new LLAdvancedCheckXUINames(), "Advanced.CheckXUINames");
|
|
view_listener_t::addMenu(new LLAdvancedSendTestIms(), "Advanced.SendTestIMs");
|
|
commit.add("Advanced.FlushNameCaches", boost::bind(&handle_flush_name_caches));
|
|
|
|
// Advanced > Character > Grab Baked Texture
|
|
view_listener_t::addMenu(new LLAdvancedGrabBakedTexture(), "Advanced.GrabBakedTexture");
|
|
view_listener_t::addMenu(new LLAdvancedEnableGrabBakedTexture(), "Advanced.EnableGrabBakedTexture");
|
|
|
|
// Advanced > Character > Character Tests
|
|
view_listener_t::addMenu(new LLAdvancedAppearanceToXML(), "Advanced.AppearanceToXML");
|
|
view_listener_t::addMenu(new LLAdvancedEnableAppearanceToXML(), "Advanced.EnableAppearanceToXML");
|
|
view_listener_t::addMenu(new LLAdvancedToggleCharacterGeometry(), "Advanced.ToggleCharacterGeometry");
|
|
|
|
view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale");
|
|
view_listener_t::addMenu(new LLAdvancedTestFemale(), "Advanced.TestFemale");
|
|
|
|
// Advanced > Character > Animation Speed
|
|
view_listener_t::addMenu(new LLAdvancedAnimTenFaster(), "Advanced.AnimTenFaster");
|
|
view_listener_t::addMenu(new LLAdvancedAnimTenSlower(), "Advanced.AnimTenSlower");
|
|
view_listener_t::addMenu(new LLAdvancedAnimResetAll(), "Advanced.AnimResetAll");
|
|
|
|
// Advanced > Character (toplevel)
|
|
view_listener_t::addMenu(new LLAdvancedForceParamsToDefault(), "Advanced.ForceParamsToDefault");
|
|
view_listener_t::addMenu(new LLAdvancedReloadVertexShader(), "Advanced.ReloadVertexShader");
|
|
view_listener_t::addMenu(new LLAdvancedToggleAnimationInfo(), "Advanced.ToggleAnimationInfo");
|
|
view_listener_t::addMenu(new LLAdvancedCheckAnimationInfo(), "Advanced.CheckAnimationInfo");
|
|
view_listener_t::addMenu(new LLAdvancedToggleShowLookAt(), "Advanced.ToggleShowLookAt");
|
|
view_listener_t::addMenu(new LLAdvancedToggleShowColor(), "Advanced.ToggleShowColor");
|
|
view_listener_t::addMenu(new LLAdvancedCheckShowColor(), "Advanced.CheckShowColor");
|
|
view_listener_t::addMenu(new LLAdvancedCheckShowLookAt(), "Advanced.CheckShowLookAt");
|
|
view_listener_t::addMenu(new LLAdvancedToggleShowPointAt(), "Advanced.ToggleShowPointAt");
|
|
view_listener_t::addMenu(new LLAdvancedCheckShowPointAt(), "Advanced.CheckShowPointAt");
|
|
view_listener_t::addMenu(new LLAdvancedTogglePrivateLookPointAt(), "Advanced.TogglePrivateLookPointAt");
|
|
view_listener_t::addMenu(new LLAdvancedCheckPrivateLookPointAt(), "Advanced.CheckPrivateLookPointAt");
|
|
view_listener_t::addMenu(new LLAdvancedToggleDebugJointUpdates(), "Advanced.ToggleDebugJointUpdates");
|
|
view_listener_t::addMenu(new LLAdvancedCheckDebugJointUpdates(), "Advanced.CheckDebugJointUpdates");
|
|
view_listener_t::addMenu(new LLAdvancedToggleDisableLOD(), "Advanced.ToggleDisableLOD");
|
|
view_listener_t::addMenu(new LLAdvancedCheckDisableLOD(), "Advanced.CheckDisableLOD");
|
|
view_listener_t::addMenu(new LLAdvancedToggleDebugCharacterVis(), "Advanced.ToggleDebugCharacterVis");
|
|
view_listener_t::addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis");
|
|
view_listener_t::addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments");
|
|
view_listener_t::addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures");
|
|
// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
|
|
commit.add("Advanced.RefreshAttachments", boost::bind(&handle_refresh_attachments));
|
|
// [/SL:KB]
|
|
view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures");
|
|
view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures");
|
|
view_listener_t::addMenu(new LLAdvancedReloadAvatarCloudParticle(), "Advanced.ReloadAvatarCloudParticle");
|
|
|
|
// Advanced > Network
|
|
view_listener_t::addMenu(new LLAdvancedEnableMessageLog(), "Advanced.EnableMessageLog");
|
|
view_listener_t::addMenu(new LLAdvancedDisableMessageLog(), "Advanced.DisableMessageLog");
|
|
view_listener_t::addMenu(new LLAdvancedDropPacket(), "Advanced.DropPacket");
|
|
|
|
// Advanced > Cache
|
|
view_listener_t::addMenu(new LLAdvancedPurgeDiskCache(), "Advanced.PurgeDiskCache");
|
|
|
|
// Advanced > Recorder
|
|
view_listener_t::addMenu(new LLAdvancedAgentPilot(), "Advanced.AgentPilot");
|
|
view_listener_t::addMenu(new LLAdvancedToggleAgentPilotLoop(), "Advanced.ToggleAgentPilotLoop");
|
|
view_listener_t::addMenu(new LLAdvancedCheckAgentPilotLoop(), "Advanced.CheckAgentPilotLoop");
|
|
view_listener_t::addMenu(new LLAdvancedViewerEventRecorder(), "Advanced.EventRecorder");
|
|
|
|
// Advanced > Debugging
|
|
view_listener_t::addMenu(new LLAdvancedForceErrorBreakpoint(), "Advanced.ForceErrorBreakpoint");
|
|
view_listener_t::addMenu(new LLAdvancedForceErrorLlerror(), "Advanced.ForceErrorLlerror");
|
|
view_listener_t::addMenu(new LLAdvancedForceErrorLlerrorMsg(), "Advanced.ForceErrorLlerrorMsg");
|
|
view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccess(), "Advanced.ForceErrorBadMemoryAccess");
|
|
view_listener_t::addMenu(new LLAdvancedForceErrorBadMemoryAccessCoro(), "Advanced.ForceErrorBadMemoryAccessCoro");
|
|
view_listener_t::addMenu(new LLAdvancedForceErrorInfiniteLoop(), "Advanced.ForceErrorInfiniteLoop");
|
|
view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareException(), "Advanced.ForceErrorSoftwareException");
|
|
view_listener_t::addMenu(new LLAdvancedForceOSException(), "Advanced.ForceErrorOSException");
|
|
view_listener_t::addMenu(new LLAdvancedForceErrorSoftwareExceptionCoro(), "Advanced.ForceErrorSoftwareExceptionCoro");
|
|
view_listener_t::addMenu(new LLAdvancedForceErrorDriverCrash(), "Advanced.ForceErrorDriverCrash");
|
|
// <FS:Ansariel> Wrongly merged back in by LL
|
|
//view_listener_t::addMenu(new LLAdvancedForceErrorCoroutineCrash(), "Advanced.ForceErrorCoroutineCrash");
|
|
view_listener_t::addMenu(new LLAdvancedForceErrorThreadCrash(), "Advanced.ForceErrorThreadCrash");
|
|
view_listener_t::addMenu(new LLAdvancedForceErrorDisconnectViewer(), "Advanced.ForceErrorDisconnectViewer");
|
|
|
|
// Advanced (toplevel)
|
|
view_listener_t::addMenu(new LLAdvancedToggleShowObjectUpdates(), "Advanced.ToggleShowObjectUpdates");
|
|
view_listener_t::addMenu(new LLAdvancedCheckShowObjectUpdates(), "Advanced.CheckShowObjectUpdates");
|
|
view_listener_t::addMenu(new LLAdvancedCompressImage(), "Advanced.CompressImage");
|
|
view_listener_t::addMenu(new LLAdvancedCompressFileTest(), "Advanced.CompressFileTest");
|
|
view_listener_t::addMenu(new LLAdvancedShowDebugSettings(), "Advanced.ShowDebugSettings");
|
|
view_listener_t::addMenu(new LLAdvancedEnableViewAdminOptions(), "Advanced.EnableViewAdminOptions");
|
|
view_listener_t::addMenu(new LLAdvancedToggleViewAdminOptions(), "Advanced.ToggleViewAdminOptions");
|
|
view_listener_t::addMenu(new LLAdvancedCheckViewAdminOptions(), "Advanced.CheckViewAdminOptions");
|
|
view_listener_t::addMenu(new LLAdvancedToggleVisualLeakDetector(), "Advanced.ToggleVisualLeakDetector");
|
|
|
|
view_listener_t::addMenu(new LLAdvancedRequestAdminStatus(), "Advanced.RequestAdminStatus");
|
|
view_listener_t::addMenu(new LLAdvancedLeaveAdminStatus(), "Advanced.LeaveAdminStatus");
|
|
|
|
// Develop >Set logging level
|
|
view_listener_t::addMenu(new LLDevelopCheckLoggingLevel(), "Develop.CheckLoggingLevel");
|
|
view_listener_t::addMenu(new LLDevelopSetLoggingLevel(), "Develop.SetLoggingLevel");
|
|
|
|
//Develop (clear cache immediately)
|
|
commit.add("Develop.ClearCache", boost::bind(&handle_cache_clear_immediately) );
|
|
|
|
// Develop (Fonts debugging)
|
|
commit.add("Develop.Fonts.Dump", boost::bind(&LLFontGL::dumpFonts));
|
|
commit.add("Develop.Fonts.DumpTextures", boost::bind(&LLFontGL::dumpFontTextures));
|
|
|
|
// <FS:Beq/> Add telemetry controls to the viewer Develop menu (Toggle profiling)
|
|
view_listener_t::addMenu(new FSProfilerToggle(), "Develop.ToggleProfiling");
|
|
view_listener_t::addMenu(new FSProfilerCheckEnabled(), "Develop.EnableProfiling");
|
|
|
|
// Admin >Object
|
|
view_listener_t::addMenu(new LLAdminForceTakeCopy(), "Admin.ForceTakeCopy");
|
|
view_listener_t::addMenu(new LLAdminHandleObjectOwnerSelf(), "Admin.HandleObjectOwnerSelf");
|
|
view_listener_t::addMenu(new LLAdminHandleObjectOwnerPermissive(), "Admin.HandleObjectOwnerPermissive");
|
|
view_listener_t::addMenu(new LLAdminHandleForceDelete(), "Admin.HandleForceDelete");
|
|
view_listener_t::addMenu(new LLAdminHandleObjectLock(), "Admin.HandleObjectLock");
|
|
view_listener_t::addMenu(new LLAdminHandleObjectAssetIDs(), "Admin.HandleObjectAssetIDs");
|
|
|
|
// Admin >Parcel
|
|
view_listener_t::addMenu(new LLAdminHandleForceParcelOwnerToMe(), "Admin.HandleForceParcelOwnerToMe");
|
|
view_listener_t::addMenu(new LLAdminHandleForceParcelToContent(), "Admin.HandleForceParcelToContent");
|
|
view_listener_t::addMenu(new LLAdminHandleClaimPublicLand(), "Admin.HandleClaimPublicLand");
|
|
|
|
// Admin >Region
|
|
view_listener_t::addMenu(new LLAdminHandleRegionDumpTempAssetData(), "Admin.HandleRegionDumpTempAssetData");
|
|
// Admin top level
|
|
view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState");
|
|
|
|
// Self context menu
|
|
view_listener_t::addMenu(new LLSelfToggleSitStand(), "Self.ToggleSitStand");
|
|
enable.add("Self.EnableSitStand", boost::bind(&enable_sit_stand));
|
|
// <FS:Ansariel> Keep this for menu check item
|
|
view_listener_t::addMenu(new LLSelfStandUp(), "Self.StandUp");
|
|
enable.add("Self.EnableStandUp", boost::bind(&enable_standup_self));
|
|
view_listener_t::addMenu(new LLSelfSitDown(), "Self.SitDown");
|
|
enable.add("Self.EnableSitDown", boost::bind(&enable_sitdown_self));
|
|
enable.add("Self.ShowSitDown", boost::bind(&show_sitdown_self));
|
|
// </FS:Ansariel>
|
|
view_listener_t::addMenu(new FSSelfForceSit(), "Self.ForceSit"); //KC
|
|
enable.add("Self.EnableForceSit", boost::bind(&enable_forcesit_self)); //KC
|
|
view_listener_t::addMenu(new FSSelfCheckForceSit(), "Self.getForceSit"); //KC
|
|
view_listener_t::addMenu(new FSSelfToggleMoveLock(), "Self.ToggleMoveLock"); //KC
|
|
view_listener_t::addMenu(new FSSelfCheckMoveLock(), "Self.GetMoveLock"); //KC
|
|
enable.add("Self.EnableMoveLock", boost::bind(&enable_move_lock)); // <FS:CR>
|
|
view_listener_t::addMenu(new FSSelfToggleIgnorePreJump(), "Self.toggleIgnorePreJump"); //SJ
|
|
view_listener_t::addMenu(new FSSelfCheckIgnorePreJump(), "Self.getIgnorePreJump"); //SJ
|
|
view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments");
|
|
|
|
view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments");
|
|
|
|
// we don't use boost::bind directly to delay side tray construction
|
|
view_listener_t::addMenu( new LLTogglePanelPeopleTab(), "SideTray.PanelPeopleTab");
|
|
view_listener_t::addMenu( new LLCheckPanelPeopleTab(), "SideTray.CheckPanelPeopleTab");
|
|
|
|
// Avatar pie menu
|
|
view_listener_t::addMenu(new LLAvatarCheckImpostorMode(), "Avatar.CheckImpostorMode");
|
|
view_listener_t::addMenu(new LLAvatarSetImpostorMode(), "Avatar.SetImpostorMode");
|
|
view_listener_t::addMenu(new LLObjectMute(), "Avatar.Mute");
|
|
view_listener_t::addMenu(new LLAvatarAddFriend(), "Avatar.AddFriend");
|
|
view_listener_t::addMenu(new LLAvatarAddContact(), "Avatar.AddContact");
|
|
commit.add("Avatar.Freeze", boost::bind(&handle_avatar_freeze, LLSD()));
|
|
view_listener_t::addMenu(new LLAvatarDebug(), "Avatar.Debug");
|
|
view_listener_t::addMenu(new LLAvatarVisibleDebug(), "Avatar.VisibleDebug");
|
|
view_listener_t::addMenu(new LLAvatarInviteToGroup(), "Avatar.InviteToGroup");
|
|
// <FS:Ansariel> FIRE-13515: Re-add give calling card
|
|
view_listener_t::addMenu(new LLAvatarGiveCard(), "Avatar.GiveCard");
|
|
// </FS:Ansariel> FIRE-13515: Re-add give calling card
|
|
commit.add("Avatar.Eject", boost::bind(&handle_avatar_eject, LLSD()));
|
|
commit.add("Avatar.ShowInspector", boost::bind(&handle_avatar_show_inspector));
|
|
view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM");
|
|
view_listener_t::addMenu(new LLAvatarCall(), "Avatar.Call");
|
|
// enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall));
|
|
// [RLVa:KB] - Checked: 2010-08-25 (RLVa-1.2.1b) | Added: RLVa-1.2.1b
|
|
enable.add("Avatar.EnableCall", boost::bind(&enable_avatar_call));
|
|
// [/RLVa:KB]
|
|
view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
|
|
view_listener_t::addMenu(new LLAvatarTexRefresh(), "Avatar.TexRefresh"); // ## Zi: Texture Refresh
|
|
|
|
view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile");
|
|
view_listener_t::addMenu(new LLAvatarTogglePicks(), "Avatar.TogglePicks");
|
|
view_listener_t::addMenu(new LLAvatarToggleSearch(), "Avatar.ToggleSearch");
|
|
view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton");
|
|
view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton");
|
|
view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations");
|
|
view_listener_t::addMenu(new LLAvatarResetSelfSkeleton(), "Avatar.ResetSelfSkeleton");
|
|
view_listener_t::addMenu(new LLAvatarResetSelfSkeletonAndAnimations(), "Avatar.ResetSelfSkeletonAndAnimations");
|
|
enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible));
|
|
enable.add("Avatar.IsPicksTabOpen", boost::bind(&picks_tab_visible));
|
|
|
|
commit.add("Avatar.OpenMarketplace", boost::bind(&LLWeb::loadURLExternal, gSavedSettings.getString("MarketplaceURL")));
|
|
|
|
view_listener_t::addMenu(new LLAvatarEnableAddFriend(), "Avatar.EnableAddFriend");
|
|
enable.add("Avatar.EnableFreezeEject", boost::bind(&enable_freeze_eject, _2));
|
|
|
|
// Object pie menu
|
|
view_listener_t::addMenu(new LLObjectBuild(), "Object.Build");
|
|
commit.add("Object.Touch", boost::bind(&handle_object_touch));
|
|
commit.add("Object.ShowOriginal", boost::bind(&handle_object_show_original));
|
|
commit.add("Object.SitOrStand", boost::bind(&handle_object_sit_or_stand));
|
|
commit.add("Object.Delete", boost::bind(&handle_object_delete));
|
|
view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar");
|
|
view_listener_t::addMenu(new LLObjectAttachToAvatar(false), "Object.AttachAddToAvatar");
|
|
view_listener_t::addMenu(new LLObjectReturn(), "Object.Return");
|
|
commit.add("Object.Duplicate", boost::bind(&LLSelectMgr::duplicate, LLSelectMgr::getInstance()));
|
|
view_listener_t::addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse");
|
|
view_listener_t::addMenu(new LLObjectMute(), "Object.Mute");
|
|
view_listener_t::addMenu(new LLObjectDerender(), "Object.Derender");
|
|
view_listener_t::addMenu(new LLObjectDerenderPermanent(), "Object.DerenderPermanent"); // <FS:Ansariel> Optional derender & blacklist
|
|
enable.add("Object.EnableDerender", boost::bind(&enable_derender_object)); // <FS:CR> FIRE-10082 - Don't enable derendering own attachments when RLVa is enabled as well
|
|
view_listener_t::addMenu(new LLObjectTexRefresh(), "Object.TexRefresh"); // ## Zi: Texture Refresh
|
|
view_listener_t::addMenu(new LLEditParticleSource(), "Object.EditParticles");
|
|
view_listener_t::addMenu(new LLEnableEditParticleSource(), "Object.EnableEditParticles");
|
|
|
|
enable.add("Object.VisibleTake", boost::bind(&visible_take_object));
|
|
enable.add("Object.VisibleTakeMultiple", boost::bind(&is_multiple_selection));
|
|
enable.add("Object.VisibleTakeSingle", boost::bind(&is_single_selection));
|
|
enable.add("Object.EnableTakeMultiple", boost::bind(&enable_take_objects));
|
|
enable.add("Object.VisibleBuy", boost::bind(&visible_buy_object));
|
|
|
|
commit.add("Object.Buy", boost::bind(&handle_buy));
|
|
commit.add("Object.Edit", boost::bind(&handle_object_edit));
|
|
commit.add("Object.EditGLTFMaterial", boost::bind(&handle_object_edit_gltf_material));
|
|
commit.add("Object.Inspect", boost::bind(&handle_object_inspect));
|
|
commit.add("Object.Open", boost::bind(&handle_object_open));
|
|
commit.add("Object.Take", boost::bind(&handle_take, false));
|
|
commit.add("Object.TakeSeparate", boost::bind(&handle_take, true));
|
|
commit.add("Object.TakeSeparateCopy", boost::bind(&handle_take_separate_copy));
|
|
commit.add("Object.ShowInspector", boost::bind(&handle_object_show_inspector));
|
|
enable.add("Object.EnableInspect", boost::bind(&enable_object_inspect));
|
|
enable.add("Object.EnableEditGLTFMaterial", boost::bind(&enable_object_edit_gltf_material));
|
|
enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
|
|
enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
|
|
enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
|
|
enable.add("Object.EnableWear", boost::bind(&object_is_wearable));
|
|
|
|
enable.add("Object.EnableStandUp", boost::bind(&enable_object_stand_up));
|
|
enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));
|
|
|
|
view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
|
|
view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
|
|
|
|
enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute));
|
|
enable.add("Object.EnableMute", boost::bind(&enable_object_mute));
|
|
enable.add("Object.EnableUnmute", boost::bind(&enable_object_unmute));
|
|
enable.add("Object.EnableBuy", boost::bind(&enable_buy_object));
|
|
commit.add("Object.ZoomIn", boost::bind(&handle_look_at_selection, "zoom"));
|
|
enable.add("Object.EnableScriptInfo", boost::bind(&enable_script_info)); // <FS:CR>
|
|
enable.add("Object.EnableShowOriginal", boost::bind(&enable_object_show_original)); // <FS:Ansariel> Disable if prevented by RLVa
|
|
|
|
|
|
// Attachment pie menu
|
|
enable.add("Attachment.Label", boost::bind(&onEnableAttachmentLabel, _1, _2));
|
|
view_listener_t::addMenu(new LLAttachmentDrop(), "Attachment.Drop");
|
|
view_listener_t::addMenu(new LLAttachmentDetachFromPoint(), "Attachment.DetachFromPoint");
|
|
view_listener_t::addMenu(new LLAttachmentDetach(), "Attachment.Detach");
|
|
view_listener_t::addMenu(new LLAttachmentPointFilled(), "Attachment.PointFilled");
|
|
view_listener_t::addMenu(new LLAttachmentEnableDrop(), "Attachment.EnableDrop");
|
|
view_listener_t::addMenu(new LLAttachmentEnableDetach(), "Attachment.EnableDetach");
|
|
|
|
// Land pie menu
|
|
view_listener_t::addMenu(new LLLandBuild(), "Land.Build");
|
|
view_listener_t::addMenu(new LLLandSit(), "Land.Sit");
|
|
view_listener_t::addMenu(new LLLandCanSit(), "Land.CanSit");
|
|
view_listener_t::addMenu(new LLLandBuyPass(), "Land.BuyPass");
|
|
view_listener_t::addMenu(new LLLandEdit(), "Land.Edit");
|
|
|
|
// Particle muting
|
|
view_listener_t::addMenu(new LLMuteParticle(), "Particle.Mute");
|
|
|
|
view_listener_t::addMenu(new LLLandEnableBuyPass(), "Land.EnableBuyPass");
|
|
commit.add("Land.Buy", boost::bind(&handle_buy_land));
|
|
|
|
// Generic actions
|
|
commit.add("ReportAbuse", boost::bind(&handle_report_abuse));
|
|
commit.add("BuyCurrency", boost::bind(&handle_buy_currency));
|
|
view_listener_t::addMenu(new LLShowHelp(), "ShowHelp");
|
|
view_listener_t::addMenu(new LLToggleHelp(), "ToggleHelp");
|
|
view_listener_t::addMenu(new LLToggleSpeak(), "ToggleSpeak");
|
|
view_listener_t::addMenu(new LLPromptShowURL(), "PromptShowURL");
|
|
view_listener_t::addMenu(new LLShowAgentProfile(), "ShowAgentProfile");
|
|
view_listener_t::addMenu(new LLShowAgentProfilePicks(), "ShowAgentProfilePicks");
|
|
view_listener_t::addMenu(new LLToggleAgentProfile(), "ToggleAgentProfile");
|
|
view_listener_t::addMenu(new LLToggleControl(), "ToggleControl");
|
|
view_listener_t::addMenu(new LLToggleShaderControl(), "ToggleShaderControl");
|
|
view_listener_t::addMenu(new LLCheckControl(), "CheckControl");
|
|
view_listener_t::addMenu(new LLGoToObject(), "GoToObject");
|
|
commit.add("PayObject", boost::bind(&handle_give_money_dialog));
|
|
|
|
// <FS:Ansariel> Control enhancements
|
|
view_listener_t::addMenu(new LLTogglePerAccountControl(), "TogglePerAccountControl");
|
|
view_listener_t::addMenu(new LLCheckPerAccountControl(), "CheckPerAccountControl");
|
|
view_listener_t::addMenu(new FSResetControl(), "ResetControl");
|
|
view_listener_t::addMenu(new FSResetPerAccountControl(), "ResetPerAccountControl");
|
|
// </FS:Ansariel> Control enhancements
|
|
|
|
// <FS:Ansariel> Reset Mesh LOD
|
|
view_listener_t::addMenu(new FSResetMeshLOD(), "Avatar.ResetMeshLOD");
|
|
|
|
commit.add("Inventory.NewWindow", boost::bind(&LLPanelMainInventory::newWindow));
|
|
|
|
enable.add("EnablePayObject", boost::bind(&enable_pay_object));
|
|
enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar));
|
|
enable.add("EnableEdit", boost::bind(&enable_object_edit));
|
|
enable.add("EnableMuteParticle", boost::bind(&enable_mute_particle));
|
|
commit.add("Pathfinding.Linksets.Select", boost::bind(&LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects));
|
|
enable.add("EnableSelectInPathfindingLinksets", boost::bind(&enable_object_select_in_pathfinding_linksets));
|
|
enable.add("VisibleSelectInPathfindingLinksets", boost::bind(&visible_object_select_in_pathfinding_linksets));
|
|
commit.add("Pathfinding.Characters.Select", boost::bind(&LLFloaterPathfindingCharacters::openCharactersWithSelectedObjects));
|
|
enable.add("EnableSelectInPathfindingCharacters", boost::bind(&enable_object_select_in_pathfinding_characters));
|
|
enable.add("Advanced.EnableErrorOSException", boost::bind(&enable_os_exception));
|
|
enable.add("EnableGLTF", boost::bind(&enable_gltf));
|
|
enable.add("EnableGLTFSaveAs", boost::bind(&enable_gltf_save_as));
|
|
enable.add("EnableGLTFUpload", boost::bind(&enable_gltf_upload));
|
|
enable.add("EnableTerrainLocalPaintMap", std::bind(&enable_terrain_local_paintmap));
|
|
enable.add("EnableBridgeFunction", boost::bind(&enable_bridge_function)); // <FS:CR>
|
|
|
|
view_listener_t::addMenu(new LLFloaterVisible(), "FloaterVisible");
|
|
view_listener_t::addMenu(new LLSomethingSelected(), "SomethingSelected");
|
|
view_listener_t::addMenu(new LLSomethingSelectedNoHUD(), "SomethingSelectedNoHUD");
|
|
view_listener_t::addMenu(new LLEditableSelected(), "EditableSelected");
|
|
view_listener_t::addMenu(new LLEditableSelectedMono(), "EditableSelectedMono");
|
|
view_listener_t::addMenu(new LLToggleUIHints(), "ToggleUIHints");
|
|
|
|
// [RLVa:KB] - Checked: RLVa-2.0.0
|
|
enable.add("RLV.MainToggleVisible", boost::bind(&rlvMenuMainToggleVisible, _1));
|
|
enable.add("RLV.CanShowName", boost::bind(&rlvMenuCanShowName));
|
|
enable.add("RLV.EnableIfNot", boost::bind(&rlvMenuEnableIfNot, _2));
|
|
// [/RLVa:KB]
|
|
|
|
// <FS:Ansariel> Toggle internal web browser
|
|
commit.add("ToggleWebBrowser", boost::bind(&toggleWebBrowser, _2));
|
|
// <FS:Ansariel> Toggle debug settings floater
|
|
commit.add("ToggleSettingsDebug", boost::bind(&toggleSettingsDebug));
|
|
// <FS:Ansariel> Toggle teleport history panel directly
|
|
commit.add("ToggleTeleportHistory", boost::bind(&toggleTeleportHistory));
|
|
// <FS:Ansariel> FIRE-7758: Save/load camera position
|
|
commit.add("Camera.StoreView", boost::bind(&LLAgentCamera::storeCameraPosition, &gAgentCamera));
|
|
commit.add("Camera.LoadView", boost::bind(&LLAgentCamera::loadCameraPosition, &gAgentCamera));
|
|
// </FS:Ansariel>
|
|
|
|
// <FS:Ansariel> Script debug floater
|
|
commit.add("ShowScriptDebug", boost::bind(&LLFloaterScriptDebug::show, LLUUID::null));
|
|
|
|
// <FS:CR> Stream list import/export
|
|
view_listener_t::addMenu(new FSStreamListExportXML(), "Streamlist.xml_export");
|
|
view_listener_t::addMenu(new FSStreamListImportXML(), "Streamlist.xml_import");
|
|
// <FS:CR> Dump SimulatorFeatures to chat
|
|
view_listener_t::addMenu(new FSDumpSimulatorFeaturesToChat(), "Develop.DumpSimFeaturesToChat");
|
|
// <FS:CR> Add to contact set
|
|
view_listener_t::addMenu(new FSAddToContactSet(), "Avatar.AddToContactSet");
|
|
|
|
// <FS:Techwolf Lupindo> export
|
|
view_listener_t::addMenu(new FSObjectExport(), "Object.Export");
|
|
view_listener_t::addMenu(new FSObjectExportCollada(), "Object.ExportCollada");
|
|
enable.add("Object.EnableExport", boost::bind(&enable_export_object));
|
|
// </FS:Techwolf Lupindo>
|
|
|
|
// <FS:Ansariel> Add avater complexity sttings to menu
|
|
view_listener_t::addMenu(new FSRenderAvatarComplexityMode(), "World.RenderAvatarComplexityMode");
|
|
view_listener_t::addMenu(new FSCheckRenderAvatarComplexityMode(), "World.CheckRenderAvatarComplexityMode");
|
|
}
|