diff options
Diffstat (limited to 'indra/newview/llviewermenu.cpp')
-rw-r--r-- | indra/newview/llviewermenu.cpp | 8810 |
1 files changed, 8810 insertions, 0 deletions
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp new file mode 100644 index 0000000000..1bf279bf2b --- /dev/null +++ b/indra/newview/llviewermenu.cpp @@ -0,0 +1,8810 @@ +/** + * @file llviewermenu.cpp + * @brief Builds menus out of items. + * + * Copyright (c) 2002-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +#include "llviewermenu.h" + +// system library includes +#include <iostream> +#include <fstream> +#include <sstream> +#include <boost/tokenizer.hpp> + +// linden library includes +#include "audioengine.h" +#include "indra_constants.h" +#include "llassetuploadresponders.h" +#include "llassetstorage.h" +#include "llchat.h" +#include "lleconomy.h" +#include "llfocusmgr.h" +#include "llfontgl.h" +#include "llinstantmessage.h" +#include "llpermissionsflags.h" +#include "llrect.h" +#include "llsecondlifeurls.h" +#include "lltransactiontypes.h" +#include "llui.h" +#include "llview.h" +#include "llxfermanager.h" +#include "message.h" +#include "raytrace.h" +#include "llsdserialize.h" +#include "lltimer.h" +#include "vorbisencode.h" +#include "llvfile.h" +#include "llvolumemgr.h" +#include "llwindow.h" // for shell_open() + +// newview includes +#include "llagent.h" +#include "llagentpilot.h" +#include "llbox.h" +#include "llcallingcard.h" +#include "llcameraview.h" +#include "llclipboard.h" +#include "llcompilequeue.h" +#include "llconsole.h" +#include "llviewercontrol.h" +#include "lldebugview.h" +#include "lldir.h" +#include "lldrawable.h" +#include "lldrawpoolalpha.h" +#include "lldrawpoolhud.h" +#include "lldrawpooltree.h" +#include "llface.h" +#include "llfirstuse.h" +#include "llfloater.h" +#include "llfloaterabout.h" +#include "llfloaterbuycurrency.h" +#include "llfloateranimpreview.h" +#include "llfloateravatarinfo.h" +#include "llfloateravatartextures.h" +#include "llfloaterbuildoptions.h" +#include "llfloaterbump.h" +#include "llfloaterbuy.h" +#include "llfloaterbuycontents.h" +#include "llfloaterbuycurrency.h" +#include "llfloaterbuyland.h" +#include "llfloaterchat.h" +#include "llfloatercustomize.h" +#include "llfloaterdirectory.h" +#include "llfloatereditui.h" +#include "llfloaterfriends.h" +#include "llfloatergesture.h" +#include "llfloatergodtools.h" +#include "llfloatergroupinfo.h" +#include "llfloatergroups.h" +#include "llfloaterhtmlhelp.h" +#include "llfloaterhtmlfind.h" +#include "llfloaterimport.h" +#include "llfloaterland.h" +#include "llfloaterlandholdings.h" +#include "llfloatermap.h" +#include "llfloateraccounthistory.h" +#include "llfloaterimagepreview.h" +#include "llfloatermute.h" +#include "llfloaternamedesc.h" +#include "llfloateropenobject.h" +#include "llfloaterpermissionsmgr.h" +#include "llfloaterpreference.h" +#include "llfloaterrate.h" +#include "llfloaterregioninfo.h" +#include "llfloaterreporter.h" +#include "llfloaterscriptdebug.h" +#include "llfloatersnapshot.h" +#include "llfloatertest.h" +#include "llfloatertools.h" +#include "llfloaterworldmap.h" +#include "llframestats.h" +#include "llframestatview.h" +#include "llfasttimerview.h" +#include "llmemoryview.h" +#include "llgivemoney.h" +#include "llgroupmgr.h" +#include "llhoverview.h" +#include "llhudeffecttrail.h" +#include "llhudmanager.h" +#include "llimage.h" +#include "llimagebmp.h" +#include "llimagej2c.h" +#include "llimagetga.h" +#include "llinventorymodel.h" +#include "llinventoryview.h" +#include "llkeyboard.h" +#include "llpanellogin.h" +#include "llmenucommands.h" +#include "llmenugl.h" +#include "llmorphview.h" +#include "llmoveview.h" +#include "llmutelist.h" +#include "llnotify.h" +#include "llpanelobject.h" +#include "llparcel.h" +#include "llpreviewscript.h" +#include "llpreviewtexture.h" +#include "llprimitive.h" +#include "llresmgr.h" +#include "llselectmgr.h" +#include "llsky.h" +#include "llstatusbar.h" +#include "llstatview.h" +#include "llstring.h" +#include "llsurfacepatch.h" +#include "llimview.h" +#include "lltextureview.h" +#include "lltool.h" +#include "lltoolbar.h" +#include "lltoolcomp.h" +#include "lltoolfocus.h" +#include "lltoolgrab.h" +#include "lltoolmgr.h" +#include "lltoolpie.h" +#include "lltoolplacer.h" +#include "lltoolselectland.h" +#include "llvieweruictrlfactory.h" +#include "lluploaddialog.h" +#include "lluserauth.h" +#include "lluuid.h" +#include "llvelocitybar.h" +#include "llviewercamera.h" +#include "llviewergesture.h" +#include "llviewerimagelist.h" +#include "llviewerinventory.h" +#include "llviewermessage.h" +#include "llviewernetwork.h" +#include "llviewerobjectlist.h" +#include "llviewerparcelmgr.h" +#include "llviewerparceloverlay.h" +#include "llviewerregion.h" +#include "llviewerstats.h" +#include "llviewerwindow.h" +#include "llvoavatar.h" +#include "llvolume.h" +#include "llweb.h" +#include "llworld.h" +#include "llworldmap.h" +#include "object_flags.h" +#include "pipeline.h" +#include "viewer.h" +#include "roles_constants.h" + +#include "lltexlayer.h" + +void init_client_menu(LLMenuGL* menu); +void init_server_menu(LLMenuGL* menu); + +void init_debug_world_menu(LLMenuGL* menu); +void init_debug_rendering_menu(LLMenuGL* menu); +void init_debug_ui_menu(LLMenuGL* menu); +void init_debug_xui_menu(LLMenuGL* menu); +void init_debug_avatar_menu(LLMenuGL* menu); +void init_debug_baked_texture_menu(LLMenuGL* menu); + +BOOL enable_land_build(void*); +BOOL enable_object_build(void*); + +LLVOAvatar* find_avatar_from_object( LLViewerObject* object ); +LLVOAvatar* find_avatar_from_object( const LLUUID& object_id ); + +void handle_test_load_url(void*); + +extern void disconnect_viewer(void *); + +// +// Evil hackish imported globals +// +extern BOOL gRenderLightGlows; +extern BOOL gRenderAvatar; +extern BOOL gHideSelectedObjects; +extern BOOL gShowOverlayTitle; +extern BOOL gRandomizeFramerate; +extern BOOL gPeriodicSlowFrame; +extern BOOL gOcclusionCull; +extern BOOL gAllowSelectAvatar; + +// +// Globals +// + +LLMenuBarGL *gMenuBarView = NULL; +LLViewerMenuHolderGL *gMenuHolder = NULL; +LLMenuGL *gPopupMenuView = NULL; + +// Pie menus +LLPieMenu *gPieSelf = NULL; +LLPieMenu *gPieAvatar = NULL; +LLPieMenu *gPieObject = NULL; +LLPieMenu *gPieAttachment = NULL; +LLPieMenu *gPieLand = NULL; + +// local constants +const LLString CLIENT_MENU_NAME("Client"); +const LLString SERVER_MENU_NAME("Server"); + +const LLString SAVE_INTO_INVENTORY("Save Object Back to My Inventory"); +const LLString SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents"); + +#if LL_WINDOWS +static const char* SOUND_EXTENSIONS = ".wav"; +static const char* IMAGE_EXTENSIONS = ".tga .bmp .jpg .jpeg"; +static const char* ANIM_EXTENSIONS = ".bvh"; +#ifdef _CORY_TESTING +static const char* GEOMETRY_EXTENSIONS = ".slg"; +#endif +static const char* XML_EXTENSIONS = ".xml"; +static const char* SLOBJECT_EXTENSIONS = ".slobject"; +#endif +static const char* ALL_FILE_EXTENSIONS = "*.*"; + +LLMenuGL* gAttachSubMenu = NULL; +LLMenuGL* gDetachSubMenu = NULL; +LLMenuGL* gTakeOffClothes = NULL; +LLPieMenu* gPieRate = NULL; +LLPieMenu* gAttachScreenPieMenu = NULL; +LLPieMenu* gAttachPieMenu = NULL; +LLPieMenu* gAttachBodyPartPieMenus[8]; +LLPieMenu* gDetachPieMenu = NULL; +LLPieMenu* gDetachScreenPieMenu = NULL; +LLPieMenu* gDetachBodyPartPieMenus[8]; + +LLMenuItemCallGL* gAFKMenu = NULL; +LLMenuItemCallGL* gBusyMenu = NULL; + +typedef LLMemberListener<LLView> view_listener_t; + +// +// Local prototypes +// +BOOL enable_attach(void*); +void handle_leave_group(void *); + +// File Menu +const char* upload_pick(void* data); +void handle_upload(void* data); +void handle_upload_object(void* data); +void handle_compress_image(void*); +BOOL enable_save_as(void *); + +// Edit menu +void handle_dump_group_info(void *); +void handle_dump_focus(void*); + +void handle_region_dump_settings(void*); +void handle_region_dump_temp_asset_data(void*); +void handle_region_clear_temp_asset_data(void*); + +// Object pie menu +BOOL sitting_on_selection(); + +void near_sit_object(); +void label_sit_or_stand(LLString& label, void*); +// 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_take(); +void confirm_take(S32 option, void* data); +BOOL enable_buy(void*); +void handle_buy(void *); +void handle_buy_object(LLSaleInfo sale_info); +void handle_buy_contents(LLSaleInfo sale_info); +void label_touch(LLString& label, void*); + +// Land pie menu +void near_sit_down_point(BOOL success, void *); + +// Avatar pie menu +void handle_follow(void *userdata); +void handle_talk_to(void *userdata); + +// Debug menu +void show_permissions_control(void*); +void load_url_local_file(const char* file_name); +void toggle_build_options(void* user_data); +#if 0 // Unused +void handle_audio_status_1(void*); +void handle_audio_status_2(void*); +void handle_audio_status_3(void*); +void handle_audio_status_4(void*); +#endif +void reload_ui(void*); +void handle_agent_stop_moving(void*); +void print_packets_lost(void*); +void drop_packet(void*); +void velocity_interpolate( void* data ); +void update_fov(S32 increments); +void toggle_wind_audio(void); +void toggle_water_audio(void); +void handle_rebake_textures(void*); +BOOL check_admin_override(void*); +void handle_admin_override_toggle(void*); +#ifdef TOGGLE_HACKED_GODLIKE_VIEWER +void handle_toggle_hacked_godmode(void*); +BOOL check_toggle_hacked_godmode(void*); +#endif + +void toggle_glow(void *); +BOOL check_glow(void *); + +void toggle_vbo(void *); +BOOL check_vbo(void *); + +void toggle_vertex_shaders(void *); +BOOL check_vertex_shaders(void *); + +void toggle_cull_small(void *); + +void toggle_show_xui_names(void *); +BOOL check_show_xui_names(void *); + +// Debug UI +void handle_save_to_xml(void*); +void handle_load_from_xml(void*); + +void handle_god_mode(void*); + +// God menu +void handle_leave_god_mode(void*); + +BOOL is_inventory_visible( void* user_data ); +void handle_reset_view(); + +void disabled_duplicate(void*); +void handle_duplicate_in_place(void*); +void handle_repeat_duplicate(void*); + +void handle_export(void*); +void handle_deed_object_to_group(void*); +BOOL enable_deed_object_to_group(void*); +void handle_object_owner_self(void*); +void handle_object_owner_permissive(void*); +void handle_object_lock(void*); +void handle_object_asset_ids(void*); +void force_take_copy(void*); +#ifdef _CORY_TESTING +void force_export_copy(void*); +void force_import_geometry(void*); +#endif + +void handle_force_parcel_owner_to_me(void*); +void handle_force_parcel_to_content(void*); +void handle_claim_public_land(void*); + +void handle_god_expunge_user(void*); + +void handle_god_request_havok(void *); +void handle_god_request_avatar_geometry(void *); // Hack for easy testing of new avatar geometry +void reload_personal_settings_overrides(void *); +void force_breakpoint(void *); +void reload_vertex_shader(void *); +void flush_animations(void *); +void slow_mo_animations(void *); +void handle_disconnect_viewer(void *); + +void handle_stopall(void*); +void handle_hinge(void*); +void handle_ptop(void*); +void handle_lptop(void*); +void handle_wheel(void*); +void handle_dehinge(void*); +BOOL enable_dehinge(void*); +void handle_force_delete(void*); +void print_object_info(void*); +void show_debug_menus(); +void toggle_debug_menus(void*); +void toggle_map( void* user_data ); +void export_info_callback(LLAssetInfo *info, void **user_data, S32 result); +void export_data_callback(LLVFS *vfs, const LLUUID& uuid, LLAssetType::EType type, void **user_data, S32 result); +void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result); +BOOL menu_check_build_tool( void* user_data ); +void handle_reload_settings(void*); +void focus_here(void*); +void dump_select_mgr(void*); +void dump_volume_mgr(void*); +void dump_inventory(void*); +void edit_ui(void*); +void toggle_visibility(void*); +BOOL get_visibility(void*); + +// Avatar Pie menu +void request_friendship(const LLUUID& agent_id); + +// Tools menu +void handle_first_tool(void*); +void handle_next_tool(void*); +void handle_previous_tool(void*); +void handle_force_unlock(void*); +void handle_selected_texture_info(void*); +void handle_dump_image_list(void*); + +void handle_fullscreen_debug(void*); +void handle_crash(void*); +void handle_dump_followcam(void*); +void handle_viewer_enable_circuit_log(void*); +void handle_viewer_disable_circuit_log(void*); +void handle_viewer_enable_message_log(void*); +void handle_viewer_disable_message_log(void*); +void handle_send_postcard(void*); +void handle_gestures_old(void*); +void handle_focus(void *); +BOOL enable_buy_land(void*); +void handle_move(void*); +void handle_show_inventory(void*); +void handle_activate(void*); +BOOL enable_activate(void*); + +// Help menu +void handle_buy_currency(void*); + +void handle_test_male(void *); +void handle_test_female(void *); +void handle_toggle_pg(void*); +void handle_dump_attachments(void *); +void handle_show_overlay_title(void*); +void handle_dump_avatar_local_textures(void*); +void handle_debug_avatar_textures(void*); +void handle_grab_texture(void*); +BOOL enable_grab_texture(void*); + +BOOL menu_ui_enabled(void *user_data); +void check_toggle_control( LLUICtrl *, void* user_data ); +BOOL menu_check_control( void* user_data); +void menu_toggle_variable( void* user_data ); +BOOL menu_check_variable( void* user_data); +BOOL enable_land_selected( void* ); +BOOL enable_more_than_one_selected(void* ); +BOOL enable_selection_you_own_all(void*); +BOOL enable_selection_you_own_one(void*); +BOOL enable_save_into_inventory(void*); +BOOL enable_save_into_task_inventory(void*); +BOOL enable_not_thirdperson(void*); +BOOL enable_export_selected(void *); +BOOL enable_have_card(void*); +BOOL enable_detach(void*); +BOOL enable_region_owner(void*); + + +class LLMenuParcelObserver : public LLParcelObserver +{ +public: + LLMenuParcelObserver(); + ~LLMenuParcelObserver(); + virtual void changed(); +}; + +static LLMenuParcelObserver* gMenuParcelObserver = NULL; + +LLMenuParcelObserver::LLMenuParcelObserver() +{ + gParcelMgr->addObserver(this); +} + +LLMenuParcelObserver::~LLMenuParcelObserver() +{ + gParcelMgr->removeObserver(this); +} + +void LLMenuParcelObserver::changed() +{ + gMenuHolder->childSetEnabled("Land Buy Pass", LLPanelLandGeneral::enableBuyPass(NULL)); + + BOOL buyable = enable_buy_land(NULL); + gMenuHolder->childSetEnabled("Land Buy", buyable); + gMenuHolder->childSetEnabled("Buy Land...", buyable); +} + + +//----------------------------------------------------------------------------- +// Menu Construction +//----------------------------------------------------------------------------- + +// code required to calculate anything about the menus +void pre_init_menus() +{ + // static information + LLColor4 color; + color = gColors.getColor( "MenuDefaultBgColor" ); + LLMenuGL::setDefaultBackgroundColor( color ); + color = gColors.getColor( "MenuItemEnabledColor" ); + LLMenuItemGL::setEnabledColor( color ); + color = gColors.getColor( "MenuItemDisabledColor" ); + LLMenuItemGL::setDisabledColor( color ); + color = gColors.getColor( "MenuItemHighlightBgColor" ); + LLMenuItemGL::setHighlightBGColor( color ); + color = gColors.getColor( "MenuItemHighlightFgColor" ); + LLMenuItemGL::setHighlightFGColor( color ); +} + +void initialize_menu_actions(); + +//----------------------------------------------------------------------------- +// 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 init_menus() +{ + S32 top = gViewerWindow->getRootView()->getRect().getHeight(); + S32 width = gViewerWindow->getRootView()->getRect().getWidth(); + + // + // Main menu bar + // + gMenuHolder = new LLViewerMenuHolderGL(); + gMenuHolder->setRect(LLRect(0, top - MENU_BAR_HEIGHT, width, STATUS_BAR_HEIGHT)); + gMenuHolder->setFollowsAll(); + + LLMenuGL::sDefaultMenuContainer = gMenuHolder; + + // Initialize actions + initialize_menu_actions(); + + gMenuBarView = (LLMenuBarGL*)gUICtrlFactory->buildMenu("menu_viewer.xml", gMenuHolder); + gMenuBarView->setRect(LLRect(0, top, width, top - MENU_BAR_HEIGHT)); + gViewerWindow->getRootView()->addChild(gMenuBarView); + + // menu holder appears on top of menu bar so you can see the menu title + // flash when an item is triggered (the flash occurs in the holder) + gViewerWindow->getRootView()->addChild(gMenuHolder); + + gMenuHolder->childSetLabelArg("Upload Image", "[COST]", "10"); + gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", "10"); + gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", "10"); + gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", "10"); + + gAFKMenu = (LLMenuItemCallGL*)gMenuBarView->getChildByName("Set Away", TRUE); + gBusyMenu = (LLMenuItemCallGL*)gMenuBarView->getChildByName("Set Busy", TRUE); + gAttachSubMenu = gMenuBarView->getChildMenuByName("Attach Object", TRUE); + gDetachSubMenu = gMenuBarView->getChildMenuByName("Detach Object", TRUE); + + if (gAgent.mAccess < SIM_ACCESS_MATURE) + { + gMenuBarView->getChildByName("Menu Underpants", TRUE)->setVisible(FALSE); + gMenuBarView->getChildByName("Menu Undershirt", TRUE)->setVisible(FALSE); + } + + // TomY TODO convert these two + LLMenuGL*menu; + menu = new LLMenuGL(CLIENT_MENU_NAME); + init_client_menu(menu); + gMenuBarView->appendMenu( menu ); + menu->updateParent(gMenuHolder); + + menu = new LLMenuGL(SERVER_MENU_NAME); + init_server_menu(menu); + gMenuBarView->appendMenu( menu ); + menu->updateParent(gMenuHolder); + + gMenuBarView->createJumpKeys(); + + /// + /// Popup menu + /// + /// The popup menu is now populated by the show_context_menu() + /// method. + + gPopupMenuView = new LLMenuGL( "Popup" ); + gPopupMenuView->setVisible( FALSE ); + gMenuHolder->addChild( gPopupMenuView ); + + /// + /// Pie menus + /// + gPieSelf = gUICtrlFactory->buildPieMenu("menu_pie_self.xml", gMenuHolder); + + // TomY TODO: what shall we do about these? + gDetachScreenPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Detach HUD", true); + gDetachPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Detach", true); + + if (gAgent.mAccess < SIM_ACCESS_MATURE) + { + gMenuHolder->getChildByName("Self Underpants", TRUE)->setVisible(FALSE); + gMenuHolder->getChildByName("Self Undershirt", TRUE)->setVisible(FALSE); + } + + gPieAvatar = gUICtrlFactory->buildPieMenu("menu_pie_avatar.xml", gMenuHolder); + + gPieObject = gUICtrlFactory->buildPieMenu("menu_pie_object.xml", gMenuHolder); + + gAttachScreenPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Attach HUD", true); + gAttachPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Attach", true); + gPieRate = (LLPieMenu*)gMenuHolder->getChildByName("Rate Menu", true); + + gPieAttachment = gUICtrlFactory->buildPieMenu("menu_pie_attachment.xml", gMenuHolder); + + gPieLand = gUICtrlFactory->buildPieMenu("menu_pie_land.xml", gMenuHolder); + + /// + /// set up the colors + /// + LLColor4 color; + + // If we are not in production, use a different color to make it apparent. + if (gInProductionGrid) + { + color = gColors.getColor( "MenuBarBgColor" ); + } + else + { + color = gColors.getColor( "MenuNonProductionBgColor" ); + } + + gMenuBarView->setBackgroundColor( color ); + + LLColor4 pie_color = gColors.getColor("PieMenuBgColor"); + gPieSelf->setBackgroundColor( pie_color ); + gPieAvatar->setBackgroundColor( pie_color ); + gPieObject->setBackgroundColor( pie_color ); + gPieAttachment->setBackgroundColor( pie_color ); + gPieLand->setBackgroundColor( pie_color ); + + color = gColors.getColor( "MenuPopupBgColor" ); + gPopupMenuView->setBackgroundColor( color ); + + // Let land based option enable when parcel changes + gMenuParcelObserver = new LLMenuParcelObserver(); + + // + // Debug menu visiblity + // + show_debug_menus(); +} + +void init_client_menu(LLMenuGL* menu) +{ + LLMenuGL* sub_menu = NULL; + + //menu->append(new LLMenuItemCallGL("Permissions Control", &show_permissions_control)); + +// this is now in the view menu so we don't need it here! + { + LLMenuGL* sub = new LLMenuGL("Consoles"); + menu->appendMenu(sub); + sub->append(new LLMenuItemCheckGL("Frame Console", + &toggle_visibility, + NULL, + &get_visibility, + (void*)gDebugView->mFrameStatView, + '2', MASK_CONTROL|MASK_SHIFT ) ); + sub->append(new LLMenuItemCheckGL("Texture Console", + &toggle_visibility, + NULL, + &get_visibility, + (void*)gTextureView, + '3', MASK_CONTROL|MASK_SHIFT ) ); + LLView* debugview = gDebugView->mDebugConsolep; + sub->append(new LLMenuItemCheckGL("Debug Console", + &toggle_visibility, + NULL, + &get_visibility, + debugview, + '4', MASK_CONTROL|MASK_SHIFT ) ); +#if 0 // Unused + { + LLMenuGL* sub = new LLMenuGL("Audio"); + menu->appendMenu(sub); + + sub->append(new LLMenuItemCallGL("Global Pos", + &handle_audio_status_1, NULL, NULL ,'5', MASK_CONTROL|MASK_SHIFT) ); + sub->append(new LLMenuItemCallGL("Cone", + &handle_audio_status_2, NULL, NULL ,'6', MASK_CONTROL|MASK_SHIFT) ); + sub->append(new LLMenuItemCallGL("Local Pos", + &handle_audio_status_3, NULL, NULL ,'7', MASK_CONTROL|MASK_SHIFT) ); + sub->append(new LLMenuItemCallGL("Duration", + &handle_audio_status_4, NULL, NULL ,'8', MASK_CONTROL|MASK_SHIFT) ); + sub->createJumpKeys(); + } +#endif + sub->append(new LLMenuItemCheckGL("Fast Timers", + &toggle_visibility, + NULL, + &get_visibility, + (void*)gDebugView->mFastTimerView, + '9', MASK_CONTROL|MASK_SHIFT ) ); + sub->append(new LLMenuItemCheckGL("Memory", + &toggle_visibility, + NULL, + &get_visibility, + (void*)gDebugView->mMemoryView, + '0', MASK_CONTROL|MASK_SHIFT ) ); + sub->appendSeparator(); + sub->append(new LLMenuItemCallGL("Region Info to Debug Console", + &handle_region_dump_settings, NULL)); + sub->append(new LLMenuItemCallGL("Group Info to Debug Console", + &handle_dump_group_info, NULL, NULL)); + sub->createJumpKeys(); + } + + // neither of these works particularly well at the moment + /*menu->append(new LLMenuItemCallGL( "Reload UI XML", &reload_ui, + NULL, NULL, 'R', MASK_ALT | MASK_CONTROL ) );*/ + /*menu->append(new LLMenuItemCallGL("Reload settings/colors", + &handle_reload_settings, NULL, NULL));*/ + menu->append(new LLMenuItemCallGL("Reload personal setting overrides", + &reload_personal_settings_overrides, NULL, NULL, KEY_F2, MASK_CONTROL|MASK_SHIFT)); + + sub_menu = new LLMenuGL("HUD Info"); + { + sub_menu->append(new LLMenuItemCheckGL("Velocity", + &toggle_visibility, + NULL, + &get_visibility, + (void*)gVelocityBar)); + + sub_menu->append(new LLMenuItemToggleGL("Camera", &gDisplayCameraPos ) ); + sub_menu->append(new LLMenuItemToggleGL("Wind", &gDisplayWindInfo) ); + sub_menu->append(new LLMenuItemToggleGL("FOV", &gDisplayFOV ) ); + sub_menu->createJumpKeys(); + } + menu->appendMenu(sub_menu); + + menu->appendSeparator(); + + menu->append(new LLMenuItemCheckGL( "High-res Snapshot", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"HighResSnapshot")); + + menu->append(new LLMenuItemToggleGL("Quiet Snapshots to Disk", + &gQuietSnapshot)); + + menu->append(new LLMenuItemCheckGL("Show Mouselook Crosshairs", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"ShowCrosshairs")); + + menu->append(new LLMenuItemCheckGL("Debug Permissions", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"DebugPermissions")); + + + +#ifdef TOGGLE_HACKED_GODLIKE_VIEWER + if (!gInProductionGrid) + { + menu->append(new LLMenuItemCheckGL("Hacked Godmode", + &handle_toggle_hacked_godmode, + NULL, + &check_toggle_hacked_godmode, + (void*)"HackedGodmode")); + } +#endif + + menu->append(new LLMenuItemCallGL("Clear Group Cache", + LLGroupMgr::debugClearAllGroups)); + menu->appendSeparator(); + + sub_menu = new LLMenuGL("Rendering"); + init_debug_rendering_menu(sub_menu); + menu->appendMenu(sub_menu); + + sub_menu = new LLMenuGL("World"); + init_debug_world_menu(sub_menu); + menu->appendMenu(sub_menu); + + sub_menu = new LLMenuGL("UI"); + init_debug_ui_menu(sub_menu); + menu->appendMenu(sub_menu); + + sub_menu = new LLMenuGL("XUI"); + init_debug_xui_menu(sub_menu); + menu->appendMenu(sub_menu); + + sub_menu = new LLMenuGL("Character"); + init_debug_avatar_menu(sub_menu); + menu->appendMenu(sub_menu); + +{ + LLMenuGL* sub = NULL; + sub = new LLMenuGL("Network"); + + sub->append(new LLMenuItemCallGL("Enable Circuit Log", + &handle_viewer_enable_circuit_log, NULL)); + sub->append(new LLMenuItemCallGL("Disable Circuit Log", + &handle_viewer_disable_circuit_log, NULL)); + sub->append(new LLMenuItemCallGL("Enable Message Log", + &handle_viewer_enable_message_log, NULL)); + sub->append(new LLMenuItemCallGL("Disable Message Log", + &handle_viewer_disable_message_log, NULL)); + + sub->appendSeparator(); + + sub->append(new LLMenuItemCheckGL("Velocity Interpolate Objects", + &velocity_interpolate, + NULL, + &menu_check_control, + (void*)"VelocityInterpolate")); + sub->append(new LLMenuItemCheckGL("Ping Interpolate Object Positions", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"PingInterpolate")); + + sub->appendSeparator(); + + sub->append(new LLMenuItemCallGL("Drop a Packet", + &drop_packet, NULL, NULL, + 'L', MASK_ALT | MASK_CONTROL)); + + menu->appendMenu( sub ); + sub->createJumpKeys(); + } + { + LLMenuGL* sub = NULL; + sub = new LLMenuGL("Recorder"); + + sub->append(new LLMenuItemCheckGL("Full Session Logging", &menu_toggle_control, NULL, &menu_check_control, (void*)"StatsSessionTrackFrameStats")); + + sub->append(new LLMenuItemCallGL("Start Logging", &LLFrameStats::startLogging, NULL)); + sub->append(new LLMenuItemCallGL("Stop Logging", &LLFrameStats::stopLogging, NULL)); + sub->append(new LLMenuItemCallGL("Log 10 Seconds", &LLFrameStats::timedLogging10, NULL)); + sub->append(new LLMenuItemCallGL("Log 30 Seconds", &LLFrameStats::timedLogging30, NULL)); + sub->append(new LLMenuItemCallGL("Log 60 Seconds", &LLFrameStats::timedLogging60, NULL)); + sub->appendSeparator(); + sub->append(new LLMenuItemCallGL("Start Playback", &LLAgentPilot::startPlayback, NULL)); + sub->append(new LLMenuItemCallGL("Stop Playback", &LLAgentPilot::stopPlayback, NULL)); + sub->append(new LLMenuItemToggleGL("Loop Playback", &LLAgentPilot::sLoop) ); + sub->append(new LLMenuItemCallGL("Start Record", &LLAgentPilot::startRecord, NULL)); + sub->append(new LLMenuItemCallGL("Stop Record", &LLAgentPilot::saveRecord, NULL)); + + menu->appendMenu( sub ); + sub->createJumpKeys(); + } + + menu->appendSeparator(); + + menu->append(new LLMenuItemToggleGL("Show Updates", + &gShowObjectUpdates, + 'U', MASK_ALT | MASK_SHIFT | MASK_CONTROL)); + + menu->appendSeparator(); + + menu->append(new LLMenuItemCallGL("Compress Image...", + &handle_compress_image, NULL, NULL)); + + menu->append(new LLMenuItemCheckGL("Limit Select Distance", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"LimitSelectDistance")); + + menu->append(new LLMenuItemToggleGL("Disable Camera Constraints", + &LLViewerCamera::sDisableCameraConstraints)); + + menu->appendSeparator(); + + menu->append(new LLMenuItemCheckGL( "Console Window", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"ShowConsoleWindow")); + +#ifndef LL_RELEASE_FOR_DOWNLOAD + { + LLMenuGL* sub = NULL; + sub = new LLMenuGL("Debugging"); + sub->append(new LLMenuItemCallGL("Force Breakpoint", &force_breakpoint, NULL, NULL, 'B', MASK_CONTROL | MASK_ALT)); + sub->append(new LLMenuItemCallGL("LLError And Crash", &handle_crash)); + sub->createJumpKeys(); + menu->appendMenu(sub); + } +#endif + + // TomY Temporary menu item so we can test this floater + menu->append(new LLMenuItemCheckGL("Clothing...", + &handle_clothing, + NULL, + NULL, + NULL)); + + menu->append(new LLMenuItemCallGL("Debug Settings", LLFloaterSettingsDebug::show, NULL, NULL)); + menu->append(new LLMenuItemCheckGL("View Admin Options", &handle_admin_override_toggle, NULL, &check_admin_override, NULL, 'V', MASK_CONTROL | MASK_ALT)); + menu->createJumpKeys(); +} + +void handle_upload_data(void*) +{ + LLFilePicker& picker = LLFilePicker::instance(); + if(!picker.getOpenFile()) + { + llwarns << "No file" << llendl; + return; + } + const char* filename = picker.getFirstFile(); + S32 index = strlen(filename); + char delim = gDirUtilp->getDirDelimiter()[0]; + while(index && filename[index--] != delim); + index += 2; + const char* basename = &filename[index]; + + LLMessageSystem* msg = gMessageSystem; + msg->newMessage("InitiateUpload"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->nextBlock("FileData"); + msg->addString("BaseFilename", basename); + msg->addString("SourceFilename", filename); + gAgent.sendReliableMessage(); +} + +void init_debug_world_menu(LLMenuGL* menu) +{ + menu->append(new LLMenuItemCheckGL("Mouse Moves Sun", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"MouseSun", + 'M', MASK_CONTROL|MASK_ALT)); + menu->append(new LLMenuItemCheckGL("Sim Sun Override", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"SkyOverrideSimSunPosition")); + menu->append(new LLMenuItemCallGL("Dump Scripted Camera", + &handle_dump_followcam, NULL, NULL)); + menu->append(new LLMenuItemCheckGL("Fixed Weather", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"FixedWeather")); + menu->createJumpKeys(); +} + + +void handle_export_menus_to_xml(void*) +{ + LLFilePicker& picker = LLFilePicker::instance(); + if(!picker.getSaveFile(LLFilePicker::FFSAVE_XML)) + { + llwarns << "No file" << llendl; + return; + } + const char* filename = picker.getFirstFile(); + + llofstream out(filename); + LLXMLNodePtr node = gMenuBarView->getXML(); + node->writeToOstream(out); + out.close(); +} + +extern BOOL gDebugClicks; +extern BOOL gDebugWindowProc; +extern BOOL gDebugTextEditorTips; +extern BOOL gDebugSelectMgr; + +void init_debug_ui_menu(LLMenuGL* menu) +{ + menu->append(new LLMenuItemCallGL("Editable UI", &edit_ui)); + menu->append(new LLMenuItemToggleGL("Async Keystrokes", &gHandleKeysAsync)); + menu->append(new LLMenuItemCallGL( "Dump SelectMgr", &dump_select_mgr)); + menu->append(new LLMenuItemCallGL( "Dump Inventory", &dump_inventory)); + menu->append(new LLMenuItemCallGL( "Dump Focus Holder", &handle_dump_focus, NULL, NULL, 'F', MASK_ALT | MASK_CONTROL)); + menu->append(new LLMenuItemCallGL( "Dump VolumeMgr", &dump_volume_mgr, NULL, NULL)); + menu->append(new LLMenuItemCallGL( "Print Selected Object Info", &print_object_info, NULL, NULL, 'P', MASK_CONTROL|MASK_SHIFT )); + menu->append(new LLMenuItemCallGL( "Print Agent Info", &print_agent_nvpairs, NULL, NULL, 'P', MASK_SHIFT )); + menu->append(new LLMenuItemCallGL( "Print Texture Memory Stats", &output_statistics, NULL, NULL, 'M', MASK_SHIFT | MASK_ALT | MASK_CONTROL)); + menu->append(new LLMenuItemCheckGL("Double-Click Auto-Pilot", + menu_toggle_control, NULL, menu_check_control, + (void*)"DoubleClickAutoPilot")); + menu->appendSeparator(); +// menu->append(new LLMenuItemCallGL( "Print Packets Lost", &print_packets_lost, NULL, NULL, 'L', MASK_SHIFT )); + menu->append(new LLMenuItemToggleGL("Debug SelectMgr", &gDebugSelectMgr)); + menu->append(new LLMenuItemToggleGL("Debug Clicks", &gDebugClicks)); + menu->append(new LLMenuItemToggleGL("Debug Views", &LLView::sDebugRects)); + menu->append(new LLMenuItemToggleGL("Debug Mouse Events", &LLView::sDebugMouseHandling)); + menu->append(new LLMenuItemToggleGL("Debug Keys", &LLView::sDebugKeys)); + menu->append(new LLMenuItemToggleGL("Debug WindowProc", &gDebugWindowProc)); + menu->append(new LLMenuItemToggleGL("Debug Text Editor Tips", &gDebugTextEditorTips)); + menu->createJumpKeys(); +} + +void init_debug_xui_menu(LLMenuGL* menu) +{ + menu->append(new LLMenuItemCallGL("Floater Test...", LLFloaterTest::show)); + menu->append(new LLMenuItemCallGL("Export Menus to XML...", handle_export_menus_to_xml)); + menu->append(new LLMenuItemCallGL("Edit UI...", LLFloaterEditUI::show)); + menu->append(new LLMenuItemCallGL("Load from XML...", handle_load_from_xml)); + menu->append(new LLMenuItemCallGL("Save to XML...", handle_save_to_xml)); + menu->append(new LLMenuItemCheckGL("Show XUI Names", toggle_show_xui_names, NULL, check_show_xui_names, NULL)); + + //menu->append(new LLMenuItemCallGL("Buy Currency...", handle_buy_currency)); + menu->createJumpKeys(); +} + +void init_debug_rendering_menu(LLMenuGL* menu) +{ + LLMenuGL* sub_menu = NULL; + + /////////////////////////// + // + // Debug menu for types/pools + // + sub_menu = new LLMenuGL("Types"); + menu->appendMenu(sub_menu); + + sub_menu->append(new LLMenuItemCheckGL("Simple", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_SIMPLE, '1', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + sub_menu->append(new LLMenuItemCheckGL("Alpha", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_ALPHA, '2', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + sub_menu->append(new LLMenuItemCheckGL("Tree", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_TREE, '3', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + sub_menu->append(new LLMenuItemCheckGL("Character", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_AVATAR, '4', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + sub_menu->append(new LLMenuItemCheckGL("SurfacePatch", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_TERRAIN, '5', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + sub_menu->append(new LLMenuItemCheckGL("Sky", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_SKY, '6', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + sub_menu->append(new LLMenuItemCheckGL("Water", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_WATER, '7', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + sub_menu->append(new LLMenuItemCheckGL("Ground", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_GROUND, '8', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + sub_menu->append(new LLMenuItemCheckGL("Volume", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_VOLUME, '9', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + sub_menu->append(new LLMenuItemCheckGL("Grass", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_GRASS, '0', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + sub_menu->append(new LLMenuItemCheckGL("Clouds", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_CLOUDS, '-', MASK_CONTROL|MASK_ALT| MASK_SHIFT)); + sub_menu->append(new LLMenuItemCheckGL("Particles", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_PARTICLES, '=', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + sub_menu->append(new LLMenuItemCheckGL("Bump", + &LLPipeline::toggleRenderType, NULL, + &LLPipeline::toggleRenderTypeControl, + (void*)LLPipeline::RENDER_TYPE_BUMP, '\\', MASK_CONTROL|MASK_ALT|MASK_SHIFT)); + sub_menu->createJumpKeys(); + sub_menu = new LLMenuGL("Features"); + menu->appendMenu(sub_menu); + sub_menu->append(new LLMenuItemCheckGL("UI", + &LLPipeline::toggleRenderDebugFeature, NULL, + &LLPipeline::toggleRenderDebugFeatureControl, + (void*)LLPipeline::RENDER_DEBUG_FEATURE_UI, '1', MASK_ALT|MASK_CONTROL)); + sub_menu->append(new LLMenuItemCheckGL("Selected", + &LLPipeline::toggleRenderDebugFeature, NULL, + &LLPipeline::toggleRenderDebugFeatureControl, + (void*)LLPipeline::RENDER_DEBUG_FEATURE_SELECTED, '2', MASK_ALT|MASK_CONTROL)); + sub_menu->append(new LLMenuItemCheckGL("Highlighted", + &LLPipeline::toggleRenderDebugFeature, NULL, + &LLPipeline::toggleRenderDebugFeatureControl, + (void*)LLPipeline::RENDER_DEBUG_FEATURE_HIGHLIGHTED, '3', MASK_ALT|MASK_CONTROL)); + sub_menu->append(new LLMenuItemCheckGL("Dynamic Textures", + &LLPipeline::toggleRenderDebugFeature, NULL, + &LLPipeline::toggleRenderDebugFeatureControl, + (void*)LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES, '4', MASK_ALT|MASK_CONTROL)); + sub_menu->append(new LLMenuItemCheckGL("Fog", + &LLPipeline::toggleRenderDebugFeature, NULL, + &LLPipeline::toggleRenderDebugFeatureControl, + (void*)LLPipeline::RENDER_DEBUG_FEATURE_FOG, '6', MASK_ALT|MASK_CONTROL)); + sub_menu->append(new LLMenuItemCheckGL("Palletized Textures", + &LLPipeline::toggleRenderDebugFeature, NULL, + &LLPipeline::toggleRenderDebugFeatureControl, + (void*)LLPipeline::RENDER_DEBUG_FEATURE_PALETTE, '7', MASK_ALT|MASK_CONTROL)); + sub_menu->append(new LLMenuItemCheckGL("Test FRInfo", + &LLPipeline::toggleRenderDebugFeature, NULL, + &LLPipeline::toggleRenderDebugFeatureControl, + (void*)LLPipeline::RENDER_DEBUG_FEATURE_FR_INFO, '8', MASK_ALT|MASK_CONTROL)); + sub_menu->append(new LLMenuItemCheckGL( "Flexible Objects", + &LLPipeline::toggleRenderDebugFeature, NULL, + &LLPipeline::toggleRenderDebugFeatureControl, + (void*)LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE, '9', MASK_ALT|MASK_CONTROL)); + sub_menu->append(new LLMenuItemCheckGL( "Chain Faces", + &LLPipeline::toggleRenderDebugFeature, NULL, + &LLPipeline::toggleRenderDebugFeatureControl, + (void*)LLPipeline::RENDER_DEBUG_FEATURE_CHAIN_FACES, '0', MASK_ALT|MASK_CONTROL)); + sub_menu->createJumpKeys(); + + ///////////////////////////// + // + // Debug menu for info displays + // + sub_menu = new LLMenuGL("Info Displays"); + menu->appendMenu(sub_menu); + + sub_menu->append(new LLMenuItemCheckGL("Verify", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_VERIFY)); + sub_menu->append(new LLMenuItemCheckGL("AGP Map", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_AGP_MEM)); + sub_menu->append(new LLMenuItemCheckGL("BBoxes", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_BBOXES)); + sub_menu->append(new LLMenuItemCheckGL("Points", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_POINTS)); + sub_menu->append(new LLMenuItemCheckGL("Octree", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_OCTREE)); + sub_menu->append(new LLMenuItemCheckGL("Occlusion", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_OCCLUSION)); + sub_menu->append(new LLMenuItemCheckGL("Face Chains", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_FACE_CHAINS)); + sub_menu->append(new LLMenuItemCheckGL("Texture Priority", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY)); + sub_menu->append(new LLMenuItemCheckGL("Composition", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_COMPOSITION)); + sub_menu->append(new LLMenuItemCheckGL("ShadowMap", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_SHADOW_MAP)); + sub_menu->append(new LLMenuItemCheckGL("LightTrace",&LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_LIGHT_TRACE)); + sub_menu->append(new LLMenuItemCheckGL("Pools", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_POOLS)); + sub_menu->append(new LLMenuItemCheckGL("Queues", &LLPipeline::toggleRenderDebug, NULL, + &LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_QUEUES)); + sub_menu->append(new LLMenuItemCheckGL("Map", &LLPipeline::toggleRenderDebug, NULL, + LLPipeline::toggleRenderDebugControl, + (void*)LLPipeline::RENDER_DEBUG_MAP)); + + sub_menu->append(new LLMenuItemCheckGL("Show Depth Buffer", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"ShowDepthBuffer")); + sub_menu->append(new LLMenuItemToggleGL("Show Select Buffer", &gDebugSelect)); + + sub_menu = new LLMenuGL("Render Tests"); + + sub_menu->append(new LLMenuItemCheckGL("Camera Offset", + &menu_toggle_control, + NULL, + &menu_check_control, + (void*)"CameraOffset")); + + sub_menu->append(new LLMenuItemToggleGL("Randomize Framerate", &gRandomizeFramerate)); + + sub_menu->append(new LLMenuItemToggleGL("Periodic Slow Frame", &gPeriodicSlowFrame)); + sub_menu->createJumpKeys(); + + menu->appendMenu( sub_menu ); + + menu->appendSeparator(); + menu->append(new LLMenuItemCheckGL("Axes", menu_toggle_control, NULL, menu_check_control, (void*)"ShowAxes")); + menu->append(new LLMenuItemCheckGL("Use VBO", toggle_vbo, NULL, check_vbo, NULL)); + menu->append(new LLMenuItemCheckGL("Light Glows", toggle_glow, NULL, check_glow, NULL)); +// menu->append(new LLMenuItemCheckGL("Cull Small Objects", toggle_cull_small, NULL, menu_check_control, (void*)"RenderCullBySize")); + + menu->appendSeparator(); + menu->append(new LLMenuItemToggleGL("Hide Selected", &gHideSelectedObjects)); + menu->appendSeparator(); + menu->append(new LLMenuItemCheckGL("Tangent Basis", menu_toggle_control, NULL, menu_check_control, (void*)"ShowTangentBasis")); + menu->append(new LLMenuItemCallGL("Selected Texture Info", handle_selected_texture_info, NULL, NULL, 'T', MASK_CONTROL|MASK_SHIFT|MASK_ALT)); + //menu->append(new LLMenuItemCallGL("Dump Image List", handle_dump_image_list, NULL, NULL, 'I', MASK_CONTROL|MASK_SHIFT)); + + menu->append(new LLMenuItemToggleGL("Wireframe", &gUseWireframe, + 'R', MASK_CONTROL|MASK_SHIFT)); + + LLMenuItemCheckGL* item; + item = new LLMenuItemCheckGL("Object-Object Occlusion", menu_toggle_control, NULL, menu_check_control, (void*)"UseOcclusion", 'O', MASK_CONTROL|MASK_SHIFT); + item->setEnabled(gGLManager.mHasOcclusionQuery); + menu->append(item); + + + item = new LLMenuItemCheckGL("Animate Textures", menu_toggle_control, NULL, menu_check_control, (void*)"AnimateTextures", 'A', MASK_CONTROL|MASK_ALT); + menu->append(item); + + item = new LLMenuItemCheckGL("Disable Textures", menu_toggle_variable, NULL, menu_check_variable, (void*)&LLViewerImage::sDontLoadVolumeTextures); + menu->append(item); + + item = new LLMenuItemCheckGL("Cheesy Beacon", menu_toggle_control, NULL, menu_check_control, (void*)"CheesyBeacon"); + menu->append(item); + +#if 0 // 1.9.2 + item = new LLMenuItemCheckGL("Vertex Shaders", toggle_vertex_shaders, NULL, check_vertex_shaders, (void*)"VertexShaderEnable", 'V', MASK_CONTROL|MASK_ALT); + item->setEnabled(gGLManager.mHasVertexShader); + menu->append(item); +#endif + menu->createJumpKeys(); +} + +extern BOOL gDebugAvatarRotation; + +void init_debug_avatar_menu(LLMenuGL* menu) +{ + LLMenuGL* sub_menu = new LLMenuGL("Grab Baked Texture"); + init_debug_baked_texture_menu(sub_menu); + menu->appendMenu(sub_menu); + + sub_menu = new LLMenuGL("Character Tests"); + sub_menu->append(new LLMenuItemToggleGL("Go Away/AFK When Idle", + &gAllowAFK)); + + sub_menu->append(new LLMenuItemCallGL("Appearance To XML", + &LLVOAvatar::dumpArchetypeXML)); + + // HACK for easy testing of avatar geometry + sub_menu->append(new LLMenuItemCallGL( "Toggle Character Geometry", + &handle_god_request_avatar_geometry, &enable_god_customer_service, NULL)); + + sub_menu->append(new LLMenuItemCallGL("Test Male", + handle_test_male)); + + sub_menu->append(new LLMenuItemCallGL("Test Female", + handle_test_female)); + + sub_menu->append(new LLMenuItemCallGL("Toggle PG", handle_toggle_pg)); + + sub_menu->append(new LLMenuItemToggleGL("Allow Select Avatar", &gAllowSelectAvatar)); + sub_menu->createJumpKeys(); + + menu->appendMenu(sub_menu); + + menu->append(new LLMenuItemCallGL("Force Params to Default", &LLAgent::clearVisualParams, NULL)); + menu->append(new LLMenuItemCallGL("Reload Vertex Shader", &reload_vertex_shader, NULL)); + menu->append(new LLMenuItemToggleGL("Animation Info", &LLVOAvatar::sShowAnimationDebug)); + menu->append(new LLMenuItemCallGL("Flush Animations", &flush_animations, NULL)); + menu->append(new LLMenuItemCallGL("Slow Motion Animations", &slow_mo_animations, NULL)); + menu->append(new LLMenuItemToggleGL("Show Look At", &LLHUDEffectLookAt::sDebugLookAt)); + menu->append(new LLMenuItemToggleGL("Show Point At", &LLHUDEffectPointAt::sDebugPointAt)); + menu->append(new LLMenuItemToggleGL("Debug Joint Updates", &LLVOAvatar::sJointDebug)); + menu->append(new LLMenuItemToggleGL("Disable LOD", &LLViewerJoint::sDisableLOD)); + menu->append(new LLMenuItemToggleGL("Debug Character Vis", &LLVOAvatar::sDebugInvisible)); + //menu->append(new LLMenuItemToggleGL("Show Attachment Points", &LLVOAvatar::sShowAttachmentPoints)); + menu->append(new LLMenuItemToggleGL("Show Collision Plane", &LLVOAvatar::sShowFootPlane)); + menu->append(new LLMenuItemToggleGL("Show Collision Skeleton", &LLVOAvatar::sShowCollisionVolumes)); + menu->append(new LLMenuItemToggleGL("Software Blending SSE", &gGLManager.mSoftwareBlendSSE)); +#if 0 // Removed since this feature doesn't actually work as of 1.9.1 --TomY + menu->append(new LLMenuItemToggleGL("Character Load Test", &LLVOAvatar::sAvatarLoadTest)); +#endif + menu->append(new LLMenuItemToggleGL( "Display Agent Target", &LLAgent::sDebugDisplayTarget)); + menu->append(new LLMenuItemToggleGL( "Debug Rotation", &gDebugAvatarRotation)); + menu->append(new LLMenuItemCallGL("Dump Attachments", handle_dump_attachments)); + menu->append(new LLMenuItemCallGL("Rebake Textures", handle_rebake_textures)); +#ifndef LL_RELEASE_FOR_DOWNLOAD + menu->append(new LLMenuItemCallGL("Debug Avatar Textures", handle_debug_avatar_textures, NULL, NULL, 'A', MASK_SHIFT|MASK_CONTROL|MASK_ALT)); + menu->append(new LLMenuItemCallGL("Dump Local Textures", handle_dump_avatar_local_textures, NULL, NULL, 'M', MASK_SHIFT|MASK_ALT )); +#endif + menu->createJumpKeys(); +} + +void init_debug_baked_texture_menu(LLMenuGL* menu) +{ + menu->append(new LLMenuItemCallGL("Iris", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_EYES_BAKED)); + menu->append(new LLMenuItemCallGL("Head", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_HEAD_BAKED)); + menu->append(new LLMenuItemCallGL("Upper Body", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_UPPER_BAKED)); + menu->append(new LLMenuItemCallGL("Lower Body", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_LOWER_BAKED)); + menu->append(new LLMenuItemCallGL("Skirt", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_SKIRT_BAKED)); + menu->createJumpKeys(); +} + +void init_server_menu(LLMenuGL* menu) +{ + /* + { + // These messages are now trusted. We can write scripts to do + // this, and the message is unchecked for source. + LLMenuGL* sub_menu = NULL; + sub_menu = new LLMenuGL("Sim Logging"); + + sub_menu->append(new LLMenuItemCallGL("Turn off llinfos Log", + &handle_reduce_llinfo_log, &enable_god_customer_service)); + + sub_menu->append(new LLMenuItemCallGL("Normal Logging", + &handle_normal_llinfo_log, &enable_god_customer_service)); + + sub_menu->appendSeparator(); + sub_menu->append(new LLMenuItemCallGL("Enable Circuit Log", + &handle_sim_enable_circuit_log, &enable_god_customer_service)); + sub_menu->append(new LLMenuItemCallGL("Disable Circuit Log", + &handle_sim_disable_circuit_log, &enable_god_customer_service)); + sub_menu->appendSeparator(); + sub_menu->append(new LLMenuItemCallGL("Enable Message Log", + &handle_sim_enable_message_log, &enable_god_customer_service)); + sub_menu->append(new LLMenuItemCallGL("Disable Message Log", + &handle_sim_disable_message_log, &enable_god_customer_service)); + + sub_menu->appendSeparator(); + + sub_menu->append(new LLMenuItemCallGL("Fetch Message Log", + &handle_sim_fetch_message_log, &enable_god_customer_service)); + + sub_menu->append(new LLMenuItemCallGL("Fetch Log", + &handle_sim_fetch_log, &enable_god_customer_service)); + + menu->appendMenu( sub_menu ); + } + */ + + { + LLMenuGL* sub = new LLMenuGL("Object"); + menu->appendMenu(sub); + + sub->append(new LLMenuItemCallGL( "Take Copy", + &force_take_copy, &enable_god_customer_service, NULL)); +#ifdef _CORY_TESTING + sub->append(new LLMenuItemCallGL( "Export Copy", + &force_export_copy, NULL, NULL)); + sub->append(new LLMenuItemCallGL( "Import Geometry", + &force_import_geometry, NULL, NULL)); +#endif + //sub->append(new LLMenuItemCallGL( "Force Public", + // &handle_object_owner_none, NULL, NULL)); + //sub->append(new LLMenuItemCallGL( "Force Ownership/Permissive", + // &handle_object_owner_self_and_permissive, NULL, NULL, 'K', MASK_SHIFT | MASK_ALT | MASK_CONTROL)); + sub->append(new LLMenuItemCallGL( "Force Owner To Me", + &handle_object_owner_self, &enable_god_customer_service)); + sub->append(new LLMenuItemCallGL( "Force Owner Permissive", + &handle_object_owner_permissive, &enable_god_customer_service)); + //sub->append(new LLMenuItemCallGL( "Force Totally Permissive", + // &handle_object_permissive)); + sub->append(new LLMenuItemCallGL( "Delete", + &handle_force_delete, &enable_god_customer_service, NULL, KEY_DELETE, MASK_SHIFT | MASK_ALT | MASK_CONTROL)); + sub->append(new LLMenuItemCallGL( "Lock", + &handle_object_lock, &enable_god_customer_service, NULL, 'L', MASK_SHIFT | MASK_ALT | MASK_CONTROL)); + sub->append(new LLMenuItemCallGL( "Get Asset IDs", + &handle_object_asset_ids, &enable_god_customer_service, NULL, 'I', MASK_SHIFT | MASK_ALT | MASK_CONTROL)); + sub->createJumpKeys(); + } + { + LLMenuGL* sub = new LLMenuGL("Parcel"); + menu->appendMenu(sub); + + sub->append(new LLMenuItemCallGL("Owner To Me", + &handle_force_parcel_owner_to_me, + &enable_god_customer_service, NULL)); + sub->append(new LLMenuItemCallGL("Set to Linden Content", + &handle_force_parcel_to_content, + &enable_god_customer_service, NULL, + 'C', MASK_SHIFT | MASK_ALT | MASK_CONTROL)); + //sub->append(new LLMenuItemCallGL("Toggle First Land bit", + // &handle_toggle_parcel_newbie)); + sub->appendSeparator(); + sub->append(new LLMenuItemCallGL("Claim Public Land", + &handle_claim_public_land, &enable_god_customer_service)); + + sub->createJumpKeys(); + } + { + LLMenuGL* sub = new LLMenuGL("Region"); + menu->appendMenu(sub); + sub->append(new LLMenuItemCallGL("Dump Temp Asset Data", + &handle_region_dump_temp_asset_data, + &enable_god_customer_service, NULL)); + sub->createJumpKeys(); + } + menu->append(new LLMenuItemCallGL( "God Tools...", + &LLFloaterGodTools::show, &enable_god_basic, NULL)); + + menu->appendSeparator(); + + menu->append(new LLMenuItemCallGL("Upload Data File...", + &handle_upload_data, + &enable_god_customer_service, + NULL)); + + + menu->appendSeparator(); + + menu->append(new LLMenuItemCallGL("Save Region State", + &LLPanelRegionTools::onSaveState, &enable_god_customer_service, NULL)); + +// menu->append(new LLMenuItemCallGL("Force Join Group", handle_force_join_group)); + + + + menu->appendSeparator(); +// +// menu->append(new LLMenuItemCallGL( "OverlayTitle", +// &handle_show_overlay_title, &enable_god_customer_service, NULL)); + + menu->append(new LLMenuItemCallGL("Request Admin Status", + &handle_god_mode, NULL, NULL, 'G', MASK_ALT | MASK_CONTROL)); + + menu->append(new LLMenuItemCallGL("Leave Admin Status", + &handle_leave_god_mode, NULL, NULL, 'G', MASK_ALT | MASK_SHIFT | MASK_CONTROL)); + menu->createJumpKeys(); +} + +//----------------------------------------------------------------------------- +// cleanup_menus() +//----------------------------------------------------------------------------- +void cleanup_menus() +{ + delete gMenuParcelObserver; + gMenuParcelObserver = NULL; +} + +//----------------------------------------------------------------------------- +// Object pie menu +//----------------------------------------------------------------------------- + +class LLObjectRateCreator : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLFloaterRate::show(LLFloaterRate::RS_CREATOR); + return true; + } +}; + +class LLObjectRateOwner : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + // Don't allow rating of group owned objects. + LLSelectNode* node = gSelectMgr->getFirstRootNode(); + if (!node) return true; + if (node->mPermissions->isGroupOwned()) + { + gViewerWindow->alertXml("CantRateOwnedByGroup"); + return true; + } + + LLFloaterRate::show(LLFloaterRate::RS_OWNER); + return true; + } +}; + +class LLObjectReportAbuse : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLFloaterReporter::showFromObject(gLastHitObjectID); + return true; + } +}; + +// Enable only when you didn't create it, and the creator +// is not the owner. +class LLObjectEnableRateCreator : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLUUID creator_id; + LLUUID owner_id; + LLString dummy; + BOOL identical_creator = gSelectMgr->selectGetCreator(creator_id, dummy); + + BOOL new_value; + if (!identical_creator) + { + new_value = FALSE; + } + else + { + new_value = (creator_id != gAgent.getID()); + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +// Enabled if object owner isn't the agent. +class LLObjectEnableRateOwner : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLUUID owner_id; + LLString dummy; + BOOL identical_owner = gSelectMgr->selectGetOwner(owner_id, dummy); + + BOOL new_value; + if (!identical_owner) + { + new_value = FALSE; + } + else if (owner_id.isNull()) + { + new_value = FALSE; + } + else + { + new_value = (owner_id != gAgent.getID()); + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + + +// Enabled it you clicked an object +class LLObjectEnableReportAbuse : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = !gLastHitObjectID.isNull(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + + +BOOL enable_attach(void*) +{ + // All root objects must be owned by agent. + BOOL rv = FALSE; + LLViewerObject* obj = gSelectMgr->getFirstRootObject(); + if(obj) + { + rv = TRUE; + for(obj = gSelectMgr->getFirstRootObject() ; obj != NULL; obj = gSelectMgr->getNextRootObject()) + { + for (U32 child_num = 0; child_num < obj->mChildList.size(); child_num++ ) + { + LLViewerObject *child = obj->mChildList[child_num]; + if (child->isAvatar()) + { + return FALSE; + } + } + if(!obj->permMove()) + { + rv = FALSE; + break; + } + } + } + return rv; +} + + +class LLObjectTouch : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLViewerObject* object = gObjectList.findObject(gLastHitObjectID); + if (!object) return true; + + LLMessageSystem *msg = gMessageSystem; + + msg->newMessageFast(_PREHASH_ObjectGrab); + msg->nextBlockFast( _PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast( _PREHASH_ObjectData); + msg->addU32Fast( _PREHASH_LocalID, object->mLocalID); + msg->addVector3Fast(_PREHASH_GrabOffset, LLVector3::zero ); + msg->sendMessage( object->getRegion()->getHost()); + + // HACK: Hope the packets arrive safely and in order. + msg->newMessageFast(_PREHASH_ObjectDeGrab); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addU32Fast(_PREHASH_LocalID, object->mLocalID); + msg->sendMessage(object->getRegion()->getHost()); + + gSelectMgr->deselectTransient(); + return true; + } +}; + + +// One object must have touch sensor +class LLObjectEnableTouch : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLViewerObject* obj = gObjectList.findObject(gLastHitObjectID); + bool new_value = obj && obj->flagHandleTouch(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + + // HACK Update label + LLSelectNode* node = gSelectMgr->getFirstRootNode(); + if (node && node->mValid && !node->mTouchName.empty()) + { + gMenuHolder->childSetText("Object Touch", node->mTouchName); + } + else + { + gMenuHolder->childSetText("Object Touch", userdata["data"].asString()); + } + + return true; + } +}; + +void label_touch(LLString& label, void*) +{ + LLSelectNode* node = gSelectMgr->getFirstRootNode(); + if (node && node->mValid && !node->mTouchName.empty()) + { + label.assign(node->mTouchName); + } + else + { + label.assign("Touch"); + } +} + +bool handle_object_open() +{ + LLViewerObject* obj = gObjectList.findObject(gLastHitObjectID); + if(!obj) return true; + + // transient selection must be made permanent + gSelectMgr->convertTransient(); + LLFloaterOpenObject::show(); + return true; +} + +class LLObjectOpen : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + return handle_object_open(); + } +}; + +class LLObjectEnableOpen : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + // Look for contents in root object, which is all the LLFloaterOpenObject + // understands. + LLViewerObject* obj = gObjectList.findObject(gLastHitObjectID); + bool new_value = (obj != NULL); + if (new_value) + { + LLViewerObject* root = obj->getRootEdit(); + if (!root) new_value = false; + else new_value = root->allowOpen(); + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + + +class LLViewCheckBuildMode : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gToolMgr->inEdit(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +bool toggle_build_mode() +{ + if (gToolMgr->inEdit()) + { + // just reset the view, will pull us out of edit mode + handle_reset_view(); + } + else + { + if (gAgent.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") ) + { + // zoom in if we're looking at the avatar + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + gAgent.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis())); + gAgent.cameraZoomIn(0.666f); + gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD ); + } + + gCurrentToolset = gBasicToolset; + gCurrentToolset->selectTool( gToolCreate ); + + // Could be first use + LLFirstUse::useBuild(); + } + return true; +} + +class LLViewBuildMode : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + return toggle_build_mode(); + } +}; + + +class LLObjectBuild : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if (gAgent.getFocusOnAvatar() && !gToolMgr->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") ) + { + // zoom in if we're looking at the avatar + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); + gAgent.cameraZoomIn(0.666f); + gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD ); + gViewerWindow->moveCursorToCenter(); + } + else if ( gSavedSettings.getBOOL("EditCameraMovement") ) + { + gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); + gViewerWindow->moveCursorToCenter(); + } + + gCurrentToolset = gBasicToolset; + gCurrentToolset->selectTool( gToolCreate ); + + // Could be first use + LLFirstUse::useBuild(); + return true; + } +}; + +class LLObjectEdit : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + gParcelMgr->deselectLand(); + // convert transient selections to permanent + gSelectMgr->convertTransient(); + + if (gAgent.getFocusOnAvatar() && !gToolMgr->inEdit()) + { + if (gSelectMgr->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 + gAgent.setFocusGlobal(gAgent.calcFocusPositionTargetGlobal(), LLUUID::null); + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + } + else + { + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + // zoom in on object center instead of where we clicked, as we need to see the manipulator handles + gAgent.setFocusGlobal(gLastHitPosGlobal /*+ gLastHitObjectOffset*/, gLastHitObjectID); + gAgent.cameraZoomIn(0.666f); + gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD ); + gViewerWindow->moveCursorToCenter(); + } + } + + gFloaterTools->open(); + + gCurrentToolset = gBasicToolset; + gCurrentToolset->selectTool( gToolTranslate ); + + // Could be first use + LLFirstUse::useBuild(); + return true; + } +}; + + +//--------------------------------------------------------------------------- +// Land pie menu +//--------------------------------------------------------------------------- +class LLLandBuild : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + gParcelMgr->deselectLand(); + + if (gAgent.getFocusOnAvatar() && !gToolMgr->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") ) + { + // zoom in if we're looking at the avatar + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); + gAgent.cameraZoomIn(0.666f); + gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD ); + gViewerWindow->moveCursorToCenter(); + } + else if ( gSavedSettings.getBOOL("EditCameraMovement") ) + { + // otherwise just move focus + gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); + gViewerWindow->moveCursorToCenter(); + } + + + gCurrentToolset = gBasicToolset; + gCurrentToolset->selectTool( gToolCreate ); + + // Could be first use + LLFirstUse::useBuild(); + return true; + } +}; + +class LLLandBuyPass : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLPanelLandGeneral::onClickBuyPass((void *)FALSE); + return true; + } +}; + +class LLLandEnableBuyPass : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = LLPanelLandGeneral::enableBuyPass(NULL); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +// BUG: Should really check if CLICK POINT is in a parcel where you can build. +BOOL enable_land_build(void*) +{ + if (gAgent.isGodlike()) return TRUE; + if (gAgent.inPrelude()) return FALSE; + + BOOL can_build = FALSE; + LLParcel* agent_parcel = gParcelMgr->getAgentParcel(); + if (agent_parcel) + { + can_build = agent_parcel->getAllowModify(); + } + return can_build; +} + +// BUG: Should really check if OBJECT is in a parcel where you can build. +BOOL enable_object_build(void*) +{ + if (gAgent.isGodlike()) return TRUE; + if (gAgent.inPrelude()) return FALSE; + + BOOL can_build = FALSE; + LLParcel* agent_parcel = gParcelMgr->getAgentParcel(); + if (agent_parcel) + { + can_build = agent_parcel->getAllowModify(); + } + return can_build; +} + +class LLEnableEdit : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gAgent.isGodlike() || !gAgent.inPrelude(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLSelfRemoveAllAttachments : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLAgent::userRemoveAllAttachments(NULL); + return true; + } +}; + +class LLSelfEnableRemoveAllAttachments : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = false; + if (gAgent.getAvatarObject()) + { + LLVOAvatar* avatarp = gAgent.getAvatarObject(); + for (LLViewerJointAttachment* attachmentp = avatarp->mAttachmentPoints.getFirstData(); + attachmentp; + attachmentp = avatarp->mAttachmentPoints.getNextData()) + { + if (attachmentp->getObject(0)) + { + new_value = true; + break; + } + } + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +BOOL enable_has_attachments(void*) +{ + + return FALSE; +} + +//--------------------------------------------------------------------------- +// Avatar pie menu +//--------------------------------------------------------------------------- +void handle_follow(void *userdata) +{ + // follow a given avatar, ID in gLastHitObjectID + gAgent.startFollowPilot(gLastHitObjectID); +} + +class LLObjectEnableMute : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLViewerObject* object = gViewerWindow->lastObjectHit(); + bool new_value = (object != NULL); + if (new_value) + { + LLVOAvatar* avatar = find_avatar_from_object(object); + if (avatar) + { + // It's an avatar + LLNameValue *lastname = avatar->getNVPair("LastName"); + BOOL is_linden = lastname && !LLString::compareStrings(lastname->getString(), "Linden"); + BOOL is_self = avatar->isSelf(); + new_value = !is_linden && !is_self; + } + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLObjectMute : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLViewerObject* object = gViewerWindow->lastObjectHit(); + if (!object) return true; + + LLUUID id; + LLString name; + LLMute::EType type; + LLVOAvatar* avatar = find_avatar_from_object(object); + if (avatar) + { + id = avatar->getID(); + + LLNameValue *firstname = avatar->getNVPair("FirstName"); + LLNameValue *lastname = avatar->getNVPair("LastName"); + if (firstname && lastname) + { + name = firstname->getString(); + name += " "; + name += lastname->getString(); + } + + type = LLMute::AGENT; + } + else + { + // it's an object + id = object->getID(); + + LLSelectNode* node = gSelectMgr->getFirstRootNode(); + if (node) + { + name = node->mName; + } + + type = LLMute::OBJECT; + } + + LLMute mute(id, name, type); + if (gMuteListp->isMuted(mute.mID, mute.mName)) + { + gMuteListp->remove(mute); + } + else + { + gMuteListp->add(mute); + gFloaterMute->show(); + } + + gSelectMgr->deselectAll(); + return true; + } +}; + +bool handle_go_to() +{ + // JAMESDEBUG try simulator autopilot + std::vector<std::string> strings; + std::string val; + val = llformat("%g", gLastHitPosGlobal.mdV[VX]); + strings.push_back(val); + val = llformat("%g", gLastHitPosGlobal.mdV[VY]); + strings.push_back(val); + val = llformat("%g", gLastHitPosGlobal.mdV[VZ]); + strings.push_back(val); + send_generic_message("autopilot", strings); + + // Don't select anything + gSelectMgr->deselectTransient(); + + gParcelMgr->deselectLand(); + + if (gAgent.getAvatarObject() && !gSavedSettings.getBOOL("AutoPilotLocksCamera")) + { + gAgent.setFocusGlobal(gAgent.getFocusTargetGlobal(), gAgent.getAvatarObject()->getID()); + } + else + { + // Snap camera back to behind avatar + gAgent.setFocusOnAvatar(TRUE, ANIMATE); + } + + // Could be first use + LLFirstUse::useGoTo(); + return true; +} + +class LLGoToObject : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + return handle_go_to(); + } +}; + +//--------------------------------------------------------------------------- +// Parcel freeze, eject, etc. +//--------------------------------------------------------------------------- +void callback_freeze(S32 option, void* data) +{ + LLUUID* avatar_id = (LLUUID*) data; + + 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() ); + } + } + + delete avatar_id; + avatar_id = NULL; +} + +class LLAvatarFreeze : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); + if( avatar ) + { + LLUUID* avatar_id = new LLUUID( avatar->getID() ); + + gViewerWindow->alertXml("FreezeAvatar", + callback_freeze, (void*)avatar_id); + + } + return true; + } +}; + +class LLAvatarVisibleDebug : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gAgent.isGodlike(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLAvatarEnableDebug : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gAgent.isGodlike(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLAvatarDebug : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); + if( avatar ) + { + avatar->dumpLocalTextures(); + } + llinfos << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << llendl; + std::vector<std::string> strings; + strings.push_back( avatar->getID().getString() ); + LLUUID invoice; + send_generic_message("dumptempassetdata", strings, invoice); + LLFloaterAvatarTextures::show( avatar->getID() ); + return true; + } +}; + +void callback_eject(S32 option, void* data) +{ + LLUUID* avatar_id = (LLUUID*) data; + + if (0 == option || 1 == option) + { + LLMessageSystem* msg = gMessageSystem; + LLViewerObject* avatar = gObjectList.findObject(*avatar_id); + + if (avatar) + { + U32 flags = 0x0; + if (1 == option) + { + // eject and add to ban list + 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() ); + } + } + + delete avatar_id; + avatar_id = NULL; +} + +class LLAvatarEject : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); + if( avatar ) + { + LLUUID* avatar_id = new LLUUID( avatar->getID() ); + gViewerWindow->alertXml("EjectAvatar", + callback_eject, (void*)avatar_id); + + } + return true; + } +}; + +class LLAvatarEnableFreezeEject : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); + bool new_value = (avatar != NULL); + + if (new_value) + { + const LLVector3& pos = avatar->getPositionRegion(); + LLViewerRegion* region = avatar->getRegion(); + new_value = (region != NULL); + + if (new_value) + { + new_value = (region->isOwnedSelf(pos) || region->isOwnedGroup(pos)); + } + } + + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLAvatarGiveCard : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + llinfos << "handle_give_card()" << llendl; + LLViewerObject* dest = gViewerWindow->lastObjectHit(); + if(dest && dest->isAvatar()) + { + bool found_name = false; + LLString::format_map_t args; + LLNameValue* nvfirst = dest->getNVPair("FirstName"); + LLNameValue* nvlast = dest->getNVPair("LastName"); + if(nvfirst && nvlast) + { + args["[FIRST]"] = nvfirst->getString(); + args["[LAST]"] = nvlast->getString(); + 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); + LLNotifyBox::showXml("OfferedCard", args); + } + else + { + gViewerWindow->alertXml("CantOfferCallingCard", args); + } + } + return true; + } +}; + + + +void login_done(S32 which, void *user) +{ + llinfos << "Login done " << which << llendl; + + LLPanelLogin::close(); +} + + + +class LLAvatarRate : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); + if( avatar ) + { + LLFloaterRate::show( avatar->getID() ); + } + return true; + } +}; + +void callback_leave_group(S32 option, void *userdata) +{ + 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.mGroupID ); + //msg->sendReliable( gUserServer ); + gAgent.sendReliableMessage(); + } +} + +void handle_leave_group(void *) +{ + if (gAgent.getGroupID() != LLUUID::null) + { + LLString::format_map_t args; + args["[GROUP]"] = gAgent.mGroupName; + gViewerWindow->alertXml("GroupLeaveConfirmMember", args, callback_leave_group); + } +} + +void append_aggregate(LLString& string, const LLAggregatePermissions& ag_perm, PermissionBit bit, const char* txt) +{ + LLAggregatePermissions::EValue val = ag_perm.getValue(bit); + char buffer[MAX_STRING]; + buffer[0] = '\0'; + switch(val) + { + case LLAggregatePermissions::AP_NONE: + sprintf(buffer, "* %s None\n", txt); + break; + case LLAggregatePermissions::AP_SOME: + sprintf(buffer, "* %s Some\n", txt); + break; + case LLAggregatePermissions::AP_ALL: + sprintf(buffer, "* %s All\n", txt); + break; + case LLAggregatePermissions::AP_EMPTY: + default: + break; + } + string.append(buffer); +} + +const char* build_extensions_string(LLFilePicker::ELoadFilter filter) +{ + switch(filter) + { +#if LL_WINDOWS + case LLFilePicker::FFLOAD_IMAGE: + return IMAGE_EXTENSIONS; + case LLFilePicker::FFLOAD_WAV: + return SOUND_EXTENSIONS; + case LLFilePicker::FFLOAD_ANIM: + return ANIM_EXTENSIONS; + case LLFilePicker::FFLOAD_SLOBJECT: + return SLOBJECT_EXTENSIONS; +#ifdef _CORY_TESTING + case LLFilePicker::FFLOAD_GEOMETRY: + return GEOMETRY_EXTENSIONS; +#endif + case LLFilePicker::FFLOAD_XML: + return XML_EXTENSIONS; + case LLFilePicker::FFLOAD_ALL: + return ALL_FILE_EXTENSIONS; +#endif + default: + return ALL_FILE_EXTENSIONS; + } +} + + +BOOL enable_buy(void*) +{ + // In order to buy, there must only be 1 purchaseable object in + // the selection manger. + if(gSelectMgr->getRootObjectCount() != 1) return FALSE; + LLViewerObject* obj = NULL; + LLSelectNode* node = gSelectMgr->getFirstRootNode(); + if(node) + { + obj = node->getObject(); + if(!obj) return FALSE; + + if(node->mSaleInfo.isForSale() && node->mPermissions->getMaskOwner() & PERM_TRANSFER && + (node->mPermissions->getMaskOwner() & PERM_COPY || node->mSaleInfo.getSaleType() != LLSaleInfo::FS_COPY)) + { + if(obj->permAnyOwner()) return TRUE; + } + } + return FALSE; +} + +class LLObjectEnableBuy : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = enable_buy(NULL); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +// 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(!gSelectMgr->selectGetAllRootsValid()) + { + LLNotifyBox::showXml("UnableToBuyWhileDownloading"); + return; + } + + LLUUID owner_id; + LLString owner_name; + BOOL owners_identical = gSelectMgr->selectGetOwner(owner_id, owner_name); + if (!owners_identical) + { + LLNotifyBox::showXml("CannotBuyObjectsFromDifferentOwners"); + return; + } + + LLPermissions perm; + BOOL valid = gSelectMgr->selectGetPermissions(perm); + LLAggregatePermissions ag_perm; + valid &= gSelectMgr->selectGetAggregatePermissions(ag_perm); + if(!valid || !sale_info.isForSale() || !perm.allowTransferTo(gAgent.getID())) + { + LLNotifyBox::showXml("ObjectNotForSale"); + return; + } + + if(sale_info.getSalePrice() > gStatusBar->getBalance()) + { + LLFloaterBuyCurrency::buyCurrency( + "This object costs", sale_info.getSalePrice()); + return; + } + + LLFloaterBuy::show(sale_info); +} + + +void handle_buy_contents(LLSaleInfo sale_info) +{ + LLFloaterBuyContents::show(sale_info); +} + +class LLFileEnableSaveAs : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gFloaterView->getFrontmost() && gFloaterView->getFrontmost()->canSaveAs(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +void handle_region_dump_temp_asset_data(void*) +{ + llinfos << "Dumping temporary asset data to simulator logs" << llendl; + std::vector<std::string> strings; + LLUUID invoice; + send_generic_message("dumptempassetdata", strings, invoice); +} + +void handle_region_clear_temp_asset_data(void*) +{ + llinfos << "Clearing temporary asset data" << llendl; + std::vector<std::string> strings; + LLUUID invoice; + send_generic_message("cleartempassetdata", strings, invoice); +} + +void handle_region_dump_settings(void*) +{ + LLViewerRegion* regionp = gAgent.getRegion(); + if (regionp) + { + llinfos << "Damage: " << (regionp->getAllowDamage() ? "on" : "off") << llendl; + llinfos << "Landmark: " << (regionp->getAllowLandmark() ? "on" : "off") << llendl; + llinfos << "SetHome: " << (regionp->getAllowSetHome() ? "on" : "off") << llendl; + llinfos << "ResetHome: " << (regionp->getResetHomeOnTeleport() ? "on" : "off") << llendl; + llinfos << "SunFixed: " << (regionp->getSunFixed() ? "on" : "off") << llendl; + llinfos << "BlockFly: " << (regionp->getBlockFly() ? "on" : "off") << llendl; + llinfos << "AllowP2P: " << (regionp->getAllowDirectTeleport() ? "on" : "off") << llendl; + llinfos << "Water: " << (regionp->getWaterHeight()) << llendl; + } +} + +void handle_dump_group_info(void *) +{ + llinfos << "group " << gAgent.mGroupName << llendl; + llinfos << "ID " << gAgent.mGroupID << llendl; + llinfos << "powers " << gAgent.mGroupPowers << llendl; + llinfos << "title " << gAgent.mGroupTitle << llendl; + //llinfos << "insig " << gAgent.mGroupInsigniaID << llendl; +} + + +void handle_dump_focus(void *) +{ + LLView *view = gFocusMgr.getKeyboardFocus(); + + llinfos << "Keyboard focus " << (view ? view->getName() : "(none)") << llendl; +} + +class LLSelfStandUp : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + return true; + } +}; + +class LLSelfEnableStandUp : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting; + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +BOOL check_admin_override(void*) +{ + return gAgent.getAdminOverride(); +} + +void handle_admin_override_toggle(void*) +{ + if(!gAgent.getAdminOverride()) + { + gAgent.setAdminOverride(TRUE); + show_debug_menus(); + } + else gAgent.setAdminOverride(FALSE); +} + +void handle_god_mode(void*) +{ + gAgent.requestEnterGodMode(); +} + +void handle_leave_god_mode(void*) +{ + gAgent.requestLeaveGodMode(); +} + +void set_god_level(U8 god_level) +{ + U8 old_god_level = gAgent.getGodLevel(); + gAgent.setGodLevel( god_level ); + show_debug_menus(); + gIMView->refresh(); + gParcelMgr->notifyObservers(); + + // Some classifieds change visibility on god mode + LLFloaterDirectory::requestClassified(); + + // God mode changes sim visibility + gWorldMap->reset(); + gWorldMap->setCurrentLayer(0); + + // inventory in items may change in god mode + gObjectList.dirtyAllObjectInventory(); + + LLString::format_map_t args; + if(god_level > GOD_NOT) + { + args["[LEVEL]"] = llformat("%d",(S32)god_level); + if (gInProductionGrid) + { + gMenuBarView->setBackgroundColor( gColors.getColor( "MenuBarGodBgColor" ) ); + } + else + { + gMenuBarView->setBackgroundColor( gColors.getColor( "MenuNonProductionGodBgColor" ) ); + } + LLNotifyBox::showXml("EnteringGodMode", args); + } + else + { + args["[LEVEL]"] = llformat("%d",(S32)old_god_level); + if (gInProductionGrid) + { + gMenuBarView->setBackgroundColor( gColors.getColor( "MenuBarBgColor" ) ); + } + else + { + gMenuBarView->setBackgroundColor( gColors.getColor( "MenuNonProductionBgColor" ) ); + } + LLNotifyBox::showXml("LeavingGodMode", args); + } +} + +#ifdef TOGGLE_HACKED_GODLIKE_VIEWER +void handle_toggle_hacked_godmode(void*) +{ + gHackGodmode = !gHackGodmode; + set_god_level(gHackGodmode ? GOD_MAINTENANCE : GOD_NOT); +} + +BOOL check_toggle_hacked_godmode(void*) +{ + return gHackGodmode; +} +#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 + { + llwarns << "Grant godlike for wrong agent " << agent_id << llendl; + } +} + +void load_url_local_file(const char* file_name) +{ + if( gAgent.cameraMouselook() ) + { + gAgent.changeCameraToDefault(); + } + +#if LL_DARWIN || LL_LINUX + // MBW -- If the Mac client is in fullscreen mode, it needs to go windowed so the browser will be visible. + if(gViewerWindow->mWindow->getFullscreen()) + { + gViewerWindow->toggleFullscreen(TRUE); + } +#endif + + // JC - system() blocks until IE has launched. + // spawn() runs asynchronously, but opens a command prompt. + // ShellExecute() just opens the damn file with the default + // web browser. + std::string full_path = "file:///"; + full_path.append(gDirUtilp->getAppRODataDir()); + full_path.append(gDirUtilp->getDirDelimiter()); + full_path.append(file_name); + + LLWeb::loadURL(full_path.c_str()); +} + +/* +class LLHaveCallingcard : public LLInventoryCollectFunctor +{ +public: + LLHaveCallingcard(const LLUUID& agent_id); + virtual ~LLHaveCallingcard() {} + virtual bool operator()(LLInventoryCategory* cat, + LLInventoryItem* item); + BOOL isThere() const { return mIsThere;} +protected: + LLUUID mID; + BOOL mIsThere; +}; + +LLHaveCallingcard::LLHaveCallingcard(const LLUUID& agent_id) : + mID(agent_id), + mIsThere(FALSE) +{ +} + +bool LLHaveCallingcard::operator()(LLInventoryCategory* cat, + LLInventoryItem* item) +{ + if(item) + { + if((item->getType() == LLAssetType::AT_CALLINGCARD) + && (item->getCreatorUUID() == mID)) + { + mIsThere = TRUE; + } + } + return FALSE; +} +*/ + +BOOL is_agent_friend(const LLUUID& agent_id) +{ + return (LLAvatarTracker::instance().getBuddyInfo(agent_id) != NULL); +} + +BOOL is_agent_mappable(const LLUUID& agent_id) +{ + return (is_agent_friend(agent_id) && + LLAvatarTracker::instance().getBuddyInfo(agent_id)->isOnline() && + LLAvatarTracker::instance().getBuddyInfo(agent_id)->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION) + ); +} + +// Enable a menu item when you have someone's card. +/* +BOOL enable_have_card(void *userdata) +{ + LLUUID* avatar_id = (LLUUID *)userdata; + if (gAgent.isGodlike()) + { + return TRUE; + } + else if(avatar_id) + { + return is_agent_friend(*avatar_id); + } + else + { + return FALSE; + } +} +*/ + +// Enable a menu item when you don't have someone's card. +class LLAvatarEnableAddFriend : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object(gViewerWindow->lastObjectHit()); + bool new_value = avatar && !is_agent_friend(avatar->getID()); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +void request_friendship(const LLUUID& dest_id) +{ + LLViewerObject* dest = gObjectList.findObject(dest_id); + if(dest && dest->isAvatar()) + { + LLString fullname; + LLString::format_map_t args; + LLNameValue* nvfirst = dest->getNVPair("FirstName"); + LLNameValue* nvlast = dest->getNVPair("LastName"); + if(nvfirst && nvlast) + { + args["[FIRST]"] = nvfirst->getString(); + args["[LAST]"] = nvlast->getString(); + fullname = nvfirst->getString(); + fullname += " "; + fullname += nvlast->getString(); + } + if (!fullname.empty()) + { + LLFloaterFriends::requestFriendship(dest_id, fullname); + LLNotifyBox::showXml("OfferedFriendship", args); + } + else + { + gViewerWindow->alertXml("CantOfferFriendship"); + } + } +} + + +class LLEditEnableCustomizeAvatar : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gAgent.getWearablesLoaded(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +bool handle_sit_or_stand() +{ + LLViewerObject *object = gObjectList.findObject(gLastHitNonFloraObjectID); + if (!object) + { + return true; + } + + if (sitting_on_selection()) + { + gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + gSelectMgr->deselectTransient(); + return true; + } + + // get object selection offset + + if (object && object->getPCode() == LL_PCODE_VOLUME) + { + LLVector3d offset_double = gViewerWindow->lastNonFloraObjectHitOffset(); + LLVector3 offset_single; + offset_single.setVec(offset_double); + + 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_single); + + object->getRegion()->sendReliableMessage(); + + gSelectMgr->deselectTransient(); + } + return true; +} + +class LLObjectSitOrStand : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + return handle_sit_or_stand(); + } +}; + +void near_sit_down_point(BOOL success, void *) +{ + gAgent.setFlying(FALSE); + gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND); + + // Might be first sit + LLFirstUse::useSit(); +} + +class LLLandSit : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + gAgent.setControlFlags(AGENT_CONTROL_STAND_UP); + gParcelMgr->deselectLand(); + + LLVector3d posGlobal = gLastHitPosGlobal; + + LLQuaternion target_rot; + if (gAgent.getAvatarObject()) + { + target_rot = gAgent.getAvatarObject()->getRotation(); + } + else + { + target_rot = gAgent.getFrameAgent().getQuaternion(); + } + gAgent.startAutoPilotGlobal(posGlobal, "Sit", &target_rot, near_sit_down_point, NULL, 0.7f); + return true; + } +}; + +void show_permissions_control(void*) +{ + LLFloaterPermissionsMgr* floaterp = LLFloaterPermissionsMgr::show(); + floaterp->mPermissions->addPermissionsData("foo1", LLUUID::null, 0); + floaterp->mPermissions->addPermissionsData("foo2", LLUUID::null, 0); + floaterp->mPermissions->addPermissionsData("foo3", LLUUID::null, 0); +} + +#if 0 // Unused (these just modify AudioInfoPage which is not used anywhere in the code +void handle_audio_status_1(void*) +{ + S32 page = gSavedSettings.getS32("AudioInfoPage"); + if (1 == page) + { + page = 0; + } + else + { + page = 1; + } + gSavedSettings.setS32("AudioInfoPage", page); +} + +void handle_audio_status_2(void*) +{ + S32 page = gSavedSettings.getS32("AudioInfoPage"); + if (2 == page) + { + page = 0; + } + else + { + page = 2; + } + gSavedSettings.setS32("AudioInfoPage", page); +} + +void handle_audio_status_3(void*) +{ + S32 page = gSavedSettings.getS32("AudioInfoPage"); + if (3 == page) + { + page = 0; + } + else + { + page = 3; + } + gSavedSettings.setS32("AudioInfoPage", page); +} + +void handle_audio_status_4(void*) +{ + S32 page = gSavedSettings.getS32("AudioInfoPage"); + if (4 == page) + { + page = 0; + } + else + { + page = 4; + } + gSavedSettings.setS32("AudioInfoPage", page); +} +#endif + +void reload_ui(void *) +{ + gUICtrlFactory->rebuild(); +} + +class LLWorldFly : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + gAgent.toggleFlying(); + return true; + } +}; + +void handle_agent_stop_moving(void*) +{ + // stop agent + gAgent.setControlFlags(AGENT_CONTROL_STOP); + + // cancel autopilot + gAgent.stopAutoPilot(); +} + +void print_packets_lost(void*) +{ + gWorldPointer->printPacketsLost(); +} + + +void drop_packet(void*) +{ + gMessageSystem->mPacketRing.dropPackets(1); +} + + +void velocity_interpolate( void* data ) +{ + BOOL toggle = gSavedSettings.getBOOL("VelocityInterpolate"); + LLMessageSystem* msg = gMessageSystem; + if ( !toggle ) + { + msg->newMessageFast(_PREHASH_VelocityInterpolateOn); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gAgent.sendReliableMessage(); + llinfos << "Velocity Interpolation On" << llendl; + } + else + { + msg->newMessageFast(_PREHASH_VelocityInterpolateOff); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gAgent.sendReliableMessage(); + llinfos << "Velocity Interpolation Off" << llendl; + } + // BUG this is a hack because of the change in menu behavior. The + // old menu system would automatically change a control's value, + // but the new LLMenuGL system doesn't know what a control + // is. However, it's easy to distinguish between the two callers + // because LLMenuGL passes in the name of the user data (the + // control name) to the callback function, and the user data goes + // unused in the old menu code. Thus, if data is not null, then we + // need to swap the value of the control. + if( data ) + { + gSavedSettings.setBOOL( static_cast<char*>(data), !toggle ); + } +} + + +void update_fov(S32 increments) +{ + F32 old_fov = gCamera->getDefaultFOV(); + // for each increment, FoV is 20% bigger + F32 new_fov = old_fov * pow(1.2f, increments); + + // cap the FoV + new_fov = llclamp(new_fov, MIN_FIELD_OF_VIEW, MAX_FIELD_OF_VIEW); + + if (new_fov != old_fov) + { + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_AgentFOV); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode); + + msg->nextBlockFast(_PREHASH_FOVBlock); + msg->addU32Fast(_PREHASH_GenCounter, 0); + msg->addF32Fast(_PREHASH_VerticalAngle, new_fov); + + gAgent.sendReliableMessage(); + + // force agent to update dirty patches + gCamera->setDefaultFOV(new_fov); + gCamera->setView(new_fov); + } +} + +class LLViewZoomOut : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + update_fov(1); + return true; + } +}; + +class LLViewZoomIn : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + update_fov(-1); + return true; + } +}; + +class LLViewZoomDefault : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + F32 old_fov = gCamera->getView(); + // for each increment, FoV is 20% bigger + F32 new_fov = DEFAULT_FIELD_OF_VIEW; + + if (new_fov != old_fov) + { + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_AgentFOV); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode); + msg->nextBlockFast(_PREHASH_FOVBlock); + msg->addU32Fast(_PREHASH_GenCounter, 0); + msg->addF32Fast(_PREHASH_VerticalAngle, new_fov); + + gAgent.sendReliableMessage(); + + // force agent to update dirty patches + gCamera->setDefaultFOV(new_fov); + gCamera->setView(new_fov); + } + return true; + } +}; + + + +void toggle_wind_audio(void) +{ + if (gAudiop) + { + gAudiop->enableWind(!(gAudiop->isWindEnabled())); + } +} + + +// Callback for enablement +BOOL is_inventory_visible( void* user_data ) +{ + LLInventoryView* iv = reinterpret_cast<LLInventoryView*>(user_data); + if( iv ) + { + return iv->getVisible(); + } + return FALSE; +} + +void handle_show_newest_map(void*) +{ + LLFloaterWorldMap::show(NULL, FALSE); +} + +//------------------------------------------------------------------- +// Help menu functions +//------------------------------------------------------------------- + +class LLHelpMOTD : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString::format_map_t args; + args["[MOTD]"] = gAgent.mMOTD; + gViewerWindow->alertXml("MOTD", args, NULL, NULL); + return true; + } +}; + +class LLHelpLiveHelp : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + // the session_id of a 911 session will always be this agent's session id + static LLUUID session_id(LLUUID::null); + if (session_id.isNull()) + { + session_id.generate(); + } + gIMView->setFloaterOpen(TRUE); + LLDynamicArray<LLUUID> members; + members.put(gAgent.getID()); + gIMView->addSession("Help Request", IM_SESSION_911_START, session_id, members); //xui: translate + return true; + } +}; + +// +// Major mode switching +// +void reset_view_final( BOOL proceed, void* ); + +void handle_reset_view() +{ + if( (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode()) && gFloaterCustomize ) + { + // Show dialog box if needed. + gFloaterCustomize->askToSaveAllIfDirty( reset_view_final, NULL ); + } + else + { + reset_view_final( TRUE, NULL ); + } +} + +class LLViewResetView : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + handle_reset_view(); + return true; + } +}; + +// Note: extra parameters allow this function to be called from dialog. +void reset_view_final( BOOL proceed, void* ) +{ + if( !proceed ) + { + return; + } + + gAgent.changeCameraToDefault(); + + gAgent.resetView(!gFloaterTools->getVisible()); + + gViewerWindow->showCursor(); + + // Switch back to basic toolset + gCurrentToolset = gBasicToolset; + gBasicToolset->selectFirstTool(); + gToolMgr->useSelectedTool( gBasicToolset ); +} + +class LLViewLookAtLastChatter : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + gAgent.lookAtLastChat(); + return true; + } +}; + +class LLViewMouselook : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if (!gAgent.cameraMouselook()) + { + gAgent.changeCameraToMouselook(); + } + else + { + gAgent.changeCameraToDefault(); + } + return true; + } +}; + +class LLViewFullscreen : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + gViewerWindow->toggleFullscreen(TRUE); + return true; + } +}; + +class LLViewDefaultUISize : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + gSavedSettings.setF32("UIScaleFactor", 1.0f); + gSavedSettings.setBOOL("UIAutoScale", FALSE); + gViewerWindow->reshape(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight()); + return true; + } +}; + +class LLEditDuplicate : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if(gEditMenuHandler) + { + gEditMenuHandler->duplicate(); + } + return true; + } +}; + +class LLEditEnableDuplicate : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gEditMenuHandler && gEditMenuHandler->canDuplicate(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + + +void disabled_duplicate(void*) +{ + if (gSelectMgr->getFirstObject()) + { + LLNotifyBox::showXml("CopyFailed"); + } +} + +void handle_duplicate_in_place(void*) +{ + llinfos << "handle_duplicate_in_place" << llendl; + + LLVector3 offset(0.f, 0.f, 0.f); + gSelectMgr->selectDuplicate(offset, TRUE); +} + +void handle_repeat_duplicate(void*) +{ + gSelectMgr->repeatDuplicate(); +} + +void handle_deed_object_to_group(void*) +{ + LLUUID group_id; + + gSelectMgr->selectGetGroup(group_id); + gSelectMgr->sendOwner(LLUUID::null, group_id, FALSE); + gViewerStats->incStat(LLViewerStats::ST_RELEASE_COUNT); +} + +BOOL enable_deed_object_to_group(void*) +{ + if(gSelectMgr->isEmpty()) return FALSE; + LLPermissions perm; + LLUUID group_id; + + if (gSelectMgr->selectGetGroup(group_id) && + gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) && + gSelectMgr->selectGetPermissions(perm) && + perm.deedToGroup(gAgent.getID(), group_id)) + { + return TRUE; + } + return FALSE; +} + + +/* + * No longer able to support viewer side manipulations in this way + * +void god_force_inv_owner_permissive(LLViewerObject* object, + InventoryObjectList* inventory, + S32 serial_num, + void*) +{ + typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t; + item_array_t items; + + InventoryObjectList::const_iterator inv_it = inventory->begin(); + InventoryObjectList::const_iterator inv_end = inventory->end(); + for ( ; inv_it != inv_end; ++inv_it) + { + if(((*inv_it)->getType() != LLAssetType::AT_CATEGORY) + && ((*inv_it)->getType() != LLAssetType::AT_ROOT_CATEGORY)) + { + LLInventoryObject* obj = *inv_it; + LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem((LLViewerInventoryItem*)obj); + LLPermissions perm(new_item->getPermissions()); + perm.setMaskBase(PERM_ALL); + perm.setMaskOwner(PERM_ALL); + new_item->setPermissions(perm); + items.push_back(new_item); + } + } + item_array_t::iterator end = items.end(); + item_array_t::iterator it; + for(it = items.begin(); it != end; ++it) + { + // since we have the inventory item in the callback, it should not + // invalidate iteration through the selection manager. + object->updateInventory((*it), TASK_INVENTORY_ITEM_KEY, false); + } +} +*/ + +void handle_object_owner_permissive(void*) +{ + // only send this if they're a god. + if(gAgent.isGodlike()) + { + // do the objects. + gSelectMgr->setObjectPermissions(PERM_BASE, TRUE, PERM_ALL, TRUE); + gSelectMgr->setObjectPermissions(PERM_OWNER, TRUE, PERM_ALL, TRUE); + } +} + +void handle_object_owner_self(void*) +{ + // only send this if they're a god. + if(gAgent.isGodlike()) + { + gSelectMgr->sendOwner(gAgent.getID(), gAgent.getGroupID(), TRUE); + } +} + +// Shortcut to set owner permissions to not editable. +void handle_object_lock(void*) +{ + gSelectMgr->setObjectPermissions(PERM_OWNER, FALSE, PERM_MODIFY); +} + +void handle_object_asset_ids(void*) +{ + // only send this if they're a god. + if (gAgent.isGodlike()) + { + gSelectMgr->sendGodlikeRequest("objectinfo", "assetids"); + } +} + +void handle_force_parcel_owner_to_me(void*) +{ + gParcelMgr->sendParcelGodForceOwner( gAgent.getID() ); +} + +void handle_force_parcel_to_content(void*) +{ + gParcelMgr->sendParcelGodForceToContent(); +} + +void handle_claim_public_land(void*) +{ + if (gParcelMgr->getSelectionRegion() != gAgent.getRegion()) + { + LLNotifyBox::showXml("ClaimPublicLand"); + return; + } + + LLVector3d west_south_global; + LLVector3d east_north_global; + gParcelMgr->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->nextBlock("MethodData"); + msg->addString("Method", "claimpublicland"); + msg->addUUID("Invoice", LLUUID::null); + char buffer[32]; + sprintf(buffer, "%f", west_south.mV[VX]); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buffer); + sprintf(buffer, "%f", west_south.mV[VY]); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buffer); + sprintf(buffer, "%f", east_north.mV[VX]); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buffer); + sprintf(buffer, "%f", east_north.mV[VY]); + msg->nextBlock("ParamList"); + msg->addString("Parameter", buffer); + gAgent.sendReliableMessage(); +} + +//void handle_toggle_parcel_newbie(void*) +//{ +// gParcelMgr->toggleParcelGodReserveForNewbie(); +//} + +void on_expunge_user(S32 option, const LLString& text, void*) +{ + if(option == -1) return; + llinfos << "on_expunge_user(" << option << "," << text << ")" << llendl; + LLMessageSystem* msg = gMessageSystem; + LLUUID user_id; + if(user_id.set(text)) + { + msg->newMessage("GodExpungeUser"); + msg->nextBlock("AgentData"); + msg->addUUID("AgentID", gAgent.getID()); + msg->addUUID("SessionID", gAgent.getSessionID()); + msg->nextBlock("ExpungeData"); + msg->addUUID("AgentID", user_id); + msg->sendReliable(gUserServer); + } + else + { + gViewerWindow->alertXml("InvalidUUID"); + } +} + +void handle_god_expunge_user(void*) +{ + gViewerWindow->alertXmlEditText("ExpungeUser", LLString::format_map_t(), + NULL, NULL, + on_expunge_user, NULL); +} + +void handle_god_request_havok(void *) +{ + if (gAgent.isGodlike()) + { + gSelectMgr->sendGodlikeRequest("havok", "infoverbose"); + } +} + +//void handle_god_request_foo(void *) +//{ +// if (gAgent.isGodlike()) +// { +// gSelectMgr->sendGodlikeRequest(GOD_WANTS_FOO); +// } +//} + +//void handle_god_request_terrain_save(void *) +//{ +// if (gAgent.isGodlike()) +// { +// gSelectMgr->sendGodlikeRequest("terrain", "save"); +// } +//} + +//void handle_god_request_terrain_load(void *) +//{ +// if (gAgent.isGodlike()) +// { +// gSelectMgr->sendGodlikeRequest("terrain", "load"); +// } +//} + + +// HACK for easily testing new avatar geometry +void handle_god_request_avatar_geometry(void *) +{ + if (gAgent.isGodlike()) + { + gSelectMgr->sendGodlikeRequest("avatar toggle", NULL); + } +} + + +void handle_show_overlay_title(void*) +{ + gShowOverlayTitle = !gShowOverlayTitle; + gSavedSettings.setBOOL("ShowOverlayTitle", gShowOverlayTitle); +} + +void derez_objects(EDeRezDestination dest, const LLUUID& dest_id) +{ + if(gAgent.cameraMouselook()) + { + gAgent.changeCameraToDefault(); + } + //gInventoryView->setPanelOpen(TRUE); + + LLViewerObject* object = NULL; + LLSelectNode* node = gSelectMgr->getFirstRootNode(); + if(!node) return; + object = node->getObject(); + if(!object) return; + LLViewerRegion* region = object->getRegion(); + char* error = NULL; + + // Check conditions that we can't deal with, building a list of + // everything that we'll actually be derezzing. + LLDynamicArray<LLViewerObject*> derez_objects; + BOOL can_derez_current; + for( ; node != NULL; node = gSelectMgr->getNextRootNode()) + { + object = node->getObject(); + if(!object || !node->mValid) continue; + if(object->getRegion() != region) + { + // *FIX: This doesn't work at all if the some of the + // objects are in regions besides the first object + // selected. We should really support this. + + // ...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 + llwarns << "Attempt to derez deprecated AssetContainer object type not supported." << llendl; + /* + object->requestInventory(container_inventory_arrived, + (void *)(BOOL)(DRD_TAKE_INTO_AGENT_INVENTORY == dest)); + */ + continue; + } + can_derez_current = FALSE; + switch(dest) + { + case DRD_TAKE_INTO_AGENT_INVENTORY: + case DRD_TRASH: + if( (node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify()) + || (node->allowOperationOnNode(PERM_OWNER, GP_OBJECT_MANIPULATE)) ) + { + can_derez_current = TRUE; + } + break; + + case DRD_RETURN_TO_OWNER: + 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) + { + derez_objects.put(object); + } + } + + // 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)derez_objects.count() / (F32)MAX_ROOTS_PER_PACKET); + if(packets > (F32)MAX_PACKET_COUNT) + { + error = "AcquireErrorTooManyObjects"; + } + + if(!error && derez_objects.count() > 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 < derez_objects.count()) + && (objects_in_packet++ < MAX_ROOTS_PER_PACKET)) + + { + object = derez_objects.get(object_index++); + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID()); + // VEFFECT: DerezObject + LLHUDEffectSpiral* effectp = (LLHUDEffectSpiral*)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE); + effectp->setPositionGlobal(object->getPositionGlobal()); + effectp->setColor(LLColor4U(gAgent.getEffectColor())); + } + msg->sendReliable(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) + { + gViewerWindow->alertXml(error); + } +} + +class LLToolsTakeCopy : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if (gSelectMgr->isEmpty()) return true; + + const LLUUID& category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT); + derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id); + + // Only deselect if we're not building + if (!gToolMgr->inEdit()) + { + gSelectMgr->deselectTransient(); + } + return true; + } +}; + + +void callback_return_to_owner(S32 option, void* data) +{ + if (0 == option) + { + // Ignore category ID for this derez destination. + derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null); + } +} + +// You can return an object to its owner if it is on your land. +class LLObjectReturn : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if (gSelectMgr->isEmpty()) return true; + + gViewerWindow->alertXml("ReturnToOwner", + callback_return_to_owner, + NULL); + return true; + } +}; + + +// 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(LLPointer<LLEvent> event, const LLSD& userdata) + { +#ifdef HACKED_GODLIKE_VIEWER + bool new_value = true; +#else + bool new_value = false; + if (gAgent.isGodlike()) + { + new_value = true; + } + else + { + LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + // Estate owners and managers can always return objects. + if (region->canManageEstate()) + { + new_value = true; + } + else + { + LLViewerObject* obj = NULL; + for(obj = gSelectMgr->getFirstRootObject(); + obj; + obj = gSelectMgr->getNextRootObject()) + { + if (obj->isOverAgentOwnedLand() + || obj->isOverGroupOwnedLand() + || obj->permModify()) + { + new_value = true; + break; + } + } + } + } + } +#endif + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +void force_take_copy(void*) +{ + if (gSelectMgr->isEmpty()) return; + const LLUUID& category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT); + derez_objects(DRD_FORCE_TO_GOD_INVENTORY, category_id); + + // Only deselect if we're not building + if (!gToolMgr->inEdit()) + { + gSelectMgr->deselectTransient(); + } +} +#ifdef _CORY_TESTING + +void force_export_copy(void*) +{ + LLViewerObject* object = NULL; + LLSelectNode* node = gSelectMgr->getFirstNode(); + if(!node) return; + object = node->getObject(); + if(!object) return; + + + LLString proposed_name; + proposed_name.append(node->mName); + proposed_name.append( ".slg" ); + + LLViewerRegion* region = object->getRegion(); + + // Check conditions that we can't deal with, building a list of + // everything that we'll actually be derezzing. + + std::vector<LLViewerObject*> export_objects; + std::vector<std::string> export_names; + std::vector<std::string> export_descriptions; + + S32 object_index = 0; + + for( ; node != NULL; node = gSelectMgr->getNextNode()) + { + object = node->getObject(); + if(!object || !node->mValid) + { + // Clicked cancel + return; + } + if(object->getRegion() != region) + { + // Clicked cancel + return; + } + if (object->isAvatar()) + { + continue; + } + + if (object->getNVPair("AssetContainer")) + { + continue; + } + export_objects.push_back(node->getObject()); + export_names.push_back(node->mName); + export_descriptions.push_back(node->mDescription); + } + + if (export_objects.empty()) + { + return; + } + + // pick a save file + LLFilePicker& picker = LLFilePicker::instance(); + if (!picker.getSaveFile(LLFilePicker::FFSAVE_GEOMETRY, proposed_name)) + { + // Clicked cancel + return; + } + + // Copy the directory + file name + char filepath[LL_MAX_PATH]; + strcpy(filepath, picker.getFirstFile()); + + apr_file_t* fp = ll_apr_file_open(filepath, LL_APR_W); + + if (!fp) + { + return; + } + + object = export_objects[object_index]; + LLVector3 baseoffset = object->getPositionRegion(); + + apr_file_printf(fp, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n"); + apr_file_printf(fp, "<LindenGeometry>\n"); + + while(object_index < export_objects.size()) + { + apr_file_printf(fp, "<Object\n"); + apr_file_printf(fp, "\tShape='%s'\n", export_names[object_index].c_str()); + apr_file_printf(fp, "\tDescription='%s'\n", export_descriptions[object_index].c_str()); + + apr_file_printf(fp, "\tPCode='%d'\n", (U32)object->getPCode()); + apr_file_printf(fp, "\tMaterial='%d'\n", object->getMaterial()); + apr_file_printf(fp, "\tScale='%5f %5f %5f'\n", object->getScale().mV[VX], object->getScale().mV[VY], object->getScale().mV[VZ]); + LLVector3 delta = object->getPositionRegion() - baseoffset; + LLQuaternion rot = object->getRotationRegion(); + apr_file_printf(fp, "\tOffset='%5f %5f %5f'\n", delta.mV[VX], delta.mV[VY], delta.mV[VZ]); + apr_file_printf(fp, "\tOrientation='%5f %5f %5f %5f'\n", rot.mQ[VX], rot.mQ[VY], rot.mQ[VZ], rot.mQ[VS]); + const LLProfileParams pparams = object->getVolume()->getProfile().mParams; + apr_file_printf(fp, "\tShapeProfile='%d %f %f %f'\n", pparams.getCurveType(), pparams.getBegin(), pparams.getEnd(), pparams.getHollow()); + const LLPathParams paparams = object->getVolume()->getPath().mParams; + apr_file_printf(fp, "\tShapePath='%d %f %f %f %f %f %f %f %f %f %f %f %f %f'\n", + paparams.getCurveType(), paparams.getBegin(), paparams.getEnd(), paparams.getTwist(), paparams.getTwistBegin(), paparams.getScaleX(), paparams.getScaleY(), + paparams.getShearX(), paparams.getShearY(), paparams.getRadiusOffset(), paparams.getTaperX(), paparams.getTaperY(), + paparams.getRevolutions(), paparams.getSkew()); + S32 face, numfaces; + numfaces = object->getNumTEs(); + apr_file_printf(fp, "\tNumberOfFaces='%d'>\n", numfaces); + for (face = 0; face < numfaces; face++) + { + const LLTextureEntry *te = object->getTE(face); + LLColor4 color = te->getColor(); + apr_file_printf(fp, "\t<Face\n\t\tFaceColor='%d %5f %5f %5f %5f'\n", face, color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW]); + + char texture[UUID_STR_LENGTH]; + LLUUID texid = te->getID(); + texid.toString(texture); + F32 sx, sy, ox, oy; + te->getScale(&sx, &sy); + te->getOffset(&ox, &oy); + + apr_file_printf(fp, "\t\tFace='%d %5f %5f %5f %5f %5f %d %s'\n\t/>\n", face, sx, sy, ox, oy, te->getRotation(), te->getBumpShinyFullbright(), texture); + } + apr_file_printf(fp, "</Object>\n"); + object = export_objects[++object_index]; + } + + apr_file_printf(fp, "</LindenGeometry>\n"); + + fclose(fp); +} + +void undo_find_local_contact_point(LLVector3 &contact, + const LLVector3& surface_norm, + const LLQuaternion& rot, + const LLVector3& scale ) +{ + LLVector3 local_norm = surface_norm; + local_norm.rotVec( ~rot ); + + LLVector3 v[6]; + v[0].mV[VX] = -1.f; + v[1].mV[VX] = 1.f; + + v[2].mV[VY] = -1.f; + v[3].mV[VY] = 1.f; + + v[4].mV[VZ] = -1.f; + v[5].mV[VZ] = 1.f; + + contact = v[0]; + F32 cur_val = 0; + + for( S32 i = 0; i < 6; i++ ) + { + F32 val = v[i] * local_norm; + if( val < cur_val ) + { + contact = v[i]; + cur_val = val; + } + } + + contact.mV[VX] *= 0.5f * scale.mV[VX]; + contact.mV[VY] *= 0.5f * scale.mV[VY]; + contact.mV[VZ] *= 0.5f * scale.mV[VZ]; + contact.rotVec( rot ); +} + + + +void force_import_geometry(void*) +{ + LLFilePicker& picker = LLFilePicker::instance(); + if (!picker.getOpenFile(LLFilePicker::FFLOAD_GEOMETRY)) + { + llinfos << "Couldn't import objects from file" << llendl; + return; + } + + char directory[LL_MAX_PATH]; + strcpy(directory, picker.getFirstFile()); + + llinfos << "Loading LSG file " << directory << llendl; + LLXmlTree *xmlparser = new LLXmlTree(); + xmlparser->parseFile(directory, TRUE); + LLXmlTreeNode *root = xmlparser->getRoot(); + if( !root ) + { + return; + } + // header + if( !root->hasName( "LindenGeometry" ) ) + { + llwarns << "Invalid LindenGeometry file header: " << directory << llendl; + return; + } + // objects + for (LLXmlTreeNode *child = root->getChildByName( "Object" ); + child; + child = root->getNextNamedChild()) + { + // get object data + char name[255]; // Shape + char description[255]; // Description + U32 material; // Material + F32 sx, sy, sz; // Scale + LLVector3 scale; + F32 ox, oy, oz; // Offset + LLVector3 offset; + F32 rx, ry, rz, rs; // Orientation + LLQuaternion rot; + U32 curve; + F32 begin; + F32 end; + F32 hollow; + F32 twist; + F32 scx, scy; + F32 shx, shy; + F32 twist_begin; + F32 radius_offset; + F32 tx, ty; + F32 revolutions; + F32 skew; + S32 faces; + U32 pcode; + U32 flags = FLAGS_CREATE_SELECTED; + + LLString attribute; + + S32 count = 0; + + child->getAttributeString("PCode", &attribute); + pcode = atoi(attribute.c_str()); + child->getAttributeString("Shape", &attribute); + sscanf(attribute.c_str(), "%s", name); + child->getAttributeString("Description", &attribute); + sscanf(attribute.c_str(), "%s", description); + child->getAttributeString("Material", &attribute); + material = atoi(attribute.c_str()); + child->getAttributeString("Scale", &attribute); + sscanf(attribute.c_str(), "%f %f %f", &sx, &sy, &sz); + scale.setVec(sx, sy, sz); + child->getAttributeString("Offset", &attribute); + sscanf(attribute.c_str(), "%f %f %f", &ox, &oy, &oz); + offset.setVec(ox, oy, oz); + child->getAttributeString("Orientation", &attribute); + sscanf(attribute.c_str(), "%f %f %f %f", &rx, &ry, &rz, &rs); + rot.mQ[VX] = rx; + rot.mQ[VY] = ry; + rot.mQ[VZ] = rz; + rot.mQ[VS] = rs; + + child->getAttributeString("ShapeProfile", &attribute); + sscanf(attribute.c_str(), "%d %f %f %f", &curve, &begin, &end, &hollow); + LLProfileParams pparams(curve, begin, end, hollow); + child->getAttributeString("ShapePath", &attribute); + sscanf(attribute.c_str(), "%d %f %f %f %f %f %f %f %f %f %f %f %f %f", + &curve, &begin, &end, &twist, &twist_begin, &scx, &scy, &shx, ­, &radius_offset, &tx, &ty, &revolutions, &skew); + LLPathParams paparams(curve, begin, end, scx, scy, shx, shy, twist, twist_begin, radius_offset, tx, ty, revolutions, skew); + child->getAttributeString("NumberOfFaces", &attribute); + faces = atoi(attribute.c_str()); + + + + gMessageSystem->newMessageFast(_PREHASH_ObjectAdd); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID()); + + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU8Fast(_PREHASH_PCode, pcode); + gMessageSystem->addU8Fast(_PREHASH_Material, material); + gMessageSystem->addU32Fast(_PREHASH_AddFlags, flags ); + pparams.packMessage(gMessageSystem); + paparams.packMessage(gMessageSystem); + + LLVector3 forward; + forward.setVec(3.f, 0.f, 1.f); + forward = forward * gAgent.getQuat(); + + LLVector3 start = gAgent.getPositionAgent() + forward; + + start += offset; + + // offset position to make up for error introduced by placement code + LLVector3 normal(0.f, 0.f, 1.f); + LLVector3 delta; + + undo_find_local_contact_point(delta, normal, rot, scale); + + start += delta; + + gMessageSystem->addVector3Fast(_PREHASH_Scale, scale ); + gMessageSystem->addQuatFast(_PREHASH_Rotation, rot ); + gMessageSystem->addVector3Fast(_PREHASH_RayStart, start ); + gMessageSystem->addVector3Fast(_PREHASH_RayEnd, start ); + gMessageSystem->addBOOLFast(_PREHASH_BypassRaycast, TRUE ); + gMessageSystem->addBOOLFast(_PREHASH_RayEndIsIntersection, FALSE ); + + U8 state = 0; + gMessageSystem->addU8Fast(_PREHASH_State, state); + + LLUUID ray_target_id; + gMessageSystem->addUUIDFast(_PREHASH_RayTargetID, ray_target_id ); + + /* Setting TE info through ObjectAdd is no longer supported. + LLPrimitive temp_primitive; + temp_primitive.setNumTEs(faces); + for (LLXmlTreeNode *face = child->getChildByName( "Face" ); + face; + face = child->getNextNamedChild()) + { + // read the faces + U32 facenumber; + LLColor4 color; + char texture[UUID_STR_LENGTH]; + LLUUID texid; + texid.toString(texture); + F32 sx, sy, ox, oy, rot; + U8 bump; + LLTextureEntry te; + + face->getAttributeString("FaceColor", &attribute); + sscanf(attribute, "%d %f %f %f %f", &facenumber, &color.mV[VX], &color.mV[VY], &color.mV[VZ], &color.mV[VW]); + face->getAttributeString("Face", &attribute); + sscanf(attribute, "%d %f %f %f %f %f %d %s", &facenumber, &sx, &sy, &ox, &oy, &rot, &bump, texture); + texid.set(texture); + te.setColor(color); + te.setBumpShinyFullbright(bump); + te.setID(texid); + te.setRotation(rot); + te.setOffset(ox, oy); + te.setScale(sx, sy); + + temp_primitive.setTE(facenumber, te); + } + + temp_primitive.packTEMessage(gMessageSystem); + */ + gMessageSystem->sendReliable(gAgent.getRegionHost()); + } + +} +#endif + +void handle_take() +{ + // we want to use the folder this was derezzed from if it's + // available. Otherwise, derez to the normal place. + if(gSelectMgr->isEmpty()) return; + LLSelectNode* node = NULL; + LLViewerObject* object = NULL; + BOOL you_own_everything = TRUE; + + BOOL locked_but_takeable_object = FALSE; + LLUUID category_id; + for(node = gSelectMgr->getFirstRootNode(); + node != NULL; + node = gSelectMgr->getNextRootNode()) + { + 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; + } + else if(category_id != node->mFolderID) + { + // we have found two potential destinations. break out + // now and send to the default location. + category_id.setNull(); + break; + } + } + } + if(category_id.notNull()) + { + // there is an unambiguous destination. See if this agent has + // such a location and it is not in the trash. + if(!gInventory.getCategory(category_id)) + { + // nope, set to NULL. + category_id.setNull(); + } + if(category_id.notNull()) + { + LLUUID trash; + trash = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH); + if(category_id == trash || gInventory.isObjectDescendentOf(category_id, trash)) + { + category_id.setNull(); + } + } + } + if(category_id.isNull()) + { + category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT); + } + LLUUID* cat_id = new LLUUID(category_id); + if(locked_but_takeable_object || + + !you_own_everything) + { + + if(locked_but_takeable_object && you_own_everything) + { + + gViewerWindow->alertXml("ConfirmObjectTakeLock", + confirm_take, + (void*)cat_id); + + } + else if(!locked_but_takeable_object && !you_own_everything) + { + + gViewerWindow->alertXml("ConfirmObjectTakeNoOwn", + confirm_take, + (void*)cat_id); + } + else + { + gViewerWindow->alertXml("ConfirmObjectTakeLockNoOwn", + confirm_take, + (void*)cat_id); + } + + + } + + else + { + confirm_take(0, (void*)cat_id); + } +} + +void confirm_take(S32 option, void* data) +{ + LLUUID* cat_id = (LLUUID*)data; + if(!cat_id) return; + if(enable_take() && (option == 0)) + { + derez_objects(DRD_TAKE_INTO_AGENT_INVENTORY, *cat_id); + } + delete cat_id; +} + +// 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()) + { + return FALSE; + } + + LLViewerObject* object = NULL; + for(LLSelectNode* node = gSelectMgr->getFirstRootNode(); + node != NULL; + node = gSelectMgr->getNextRootNode()) + { + object = node->getObject(); + if(!object || !node->mValid) continue; + if (object->isAvatar()) + { + // ...don't acquire avatars + continue; + } + +#ifdef HACKED_GODLIKE_VIEWER + return TRUE; +#else +# ifdef TOGGLE_HACKED_GODLIKE_VIEWER + if (!gInProductionGrid && gAgent.isGodlike()) + { + return TRUE; + } +# endif + if((node->mPermissions->allowTransferTo(gAgent.getID()) + && object->permModify()) + || (node->mPermissions->getOwner() == gAgent.getID())) + { + return TRUE; + } +#endif + } + return FALSE; +} + +class LLToolsBuyOrTake : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if (gSelectMgr->isEmpty()) + { + return true; + } + + if (is_selection_buy_not_take()) + { + S32 total_price = selection_price(); + + if (total_price <= gStatusBar->getBalance()) + { + handle_buy(NULL); + } + else + { + LLFloaterBuyCurrency::buyCurrency( + "Buying this costs", total_price); + } + } + else + { + handle_take(); + } + return true; + } +}; + +class LLToolsEnableBuyOrTake : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool is_buy = is_selection_buy_not_take(); + bool new_value = is_buy ? enable_buy(NULL) : enable_take(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + + // HACK: Update label + LLString label; + LLString buy_text; + LLString take_text; + LLString param = userdata["data"].asString(); + LLString::size_type offset = param.find(","); + if (offset != param.npos) + { + buy_text = param.substr(0, offset); + take_text = param.substr(offset+1); + } + if (is_buy) + { + label = buy_text; + } + else + { + label = take_text; + } + gMenuHolder->childSetText("Pie Object Take", label); + gMenuHolder->childSetText("Menu Object Take", label); + + return true; + } +}; + +// 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() +{ + LLViewerObject* obj = NULL; + for(LLSelectNode* node = gSelectMgr->getFirstRootNode(); + node != NULL; + node = gSelectMgr->getNextRootNode()) + { + obj = node->getObject(); + if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale())) + { + // you do not own the object and it is for sale, thus, + // it's a buy + return TRUE; + } + } + return FALSE; +} + +S32 selection_price() +{ + LLViewerObject* obj = NULL; + S32 total_price = 0; + for(LLSelectNode* node = gSelectMgr->getFirstRootNode(); + node != NULL; + node = gSelectMgr->getNextRootNode()) + { + 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; +} + +void callback_show_buy_currency(S32 option, void*) +{ + if (0 == option) + { + llinfos << "Loading page " << BUY_CURRENCY_URL << llendl; + LLWeb::loadURL(BUY_CURRENCY_URL); + } +} + + +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 " << BUY_CURRENCY_URL << "\nfor information on purchasing currency?"; + + LLString::format_map_t args; + args["[EXTRA]"] = extra; + args["[URL]"] = BUY_CURRENCY_URL; + gViewerWindow->alertXml("PromptGoToCurrencyPage", args, + callback_show_buy_currency); +} + +void handle_buy_currency(void*) +{ +// LLFloaterBuyCurrency::buyCurrency(); +} + +void handle_buy(void*) +{ + if (gSelectMgr->isEmpty()) return; + + LLSaleInfo sale_info; + BOOL valid = gSelectMgr->selectGetSaleInfo(sale_info); + if (!valid) return; + + if (sale_info.getSaleType() == LLSaleInfo::FS_CONTENTS) + { + handle_buy_contents(sale_info); + } + else + { + handle_buy_object(sale_info); + } +} + +class LLObjectBuy : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + handle_buy(NULL); + return true; + } +}; + +BOOL sitting_on_selection() +{ + LLSelectNode* node = gSelectMgr->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 + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if (!avatar) + { + return FALSE; + } + + return (avatar->mIsSitting && avatar->getRoot() == root_object); +} + +class LLToolsSaveToInventory : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if(enable_save_into_inventory(NULL)) + { + derez_objects(DRD_SAVE_INTO_AGENT_INVENTORY, LLUUID::null); + } + return true; + } +}; + +class LLToolsSaveToObjectInventory : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if(gSelectMgr) + { + LLSelectNode* node = gSelectMgr->getFirstRootNode(); + if(node && (node->mValid) && (!node->mFromTaskID.isNull())) + { + // *FIX: check to see if the fromtaskid object exists. + derez_objects(DRD_SAVE_INTO_TASK_INVENTORY, node->mFromTaskID); + } + } + return true; + } +}; + +// Round the position of all root objects to the grid +class LLToolsSnapObjectXY : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + F64 snap_size = (F64)gSavedSettings.getF32("GridResolution"); + + LLViewerObject* obj; + for (obj = gSelectMgr->getFirstRootObject(); + obj != NULL; + obj = gSelectMgr->getNextRootObject()) + { + 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); + } + } + gSelectMgr->sendMultipleUpdate(UPD_POSITION); + return true; + } +}; + +// in order to link, all objects must have the same owner, and the +// agent must have the ability to modify all of the objects. However, +// we're not answering that question with this method. The question +// we're answering is: does the user have a reasonable expectation +// that a link operation should work? If so, return true, false +// otherwise. this allows the handle_link method to more finely check +// the selection and give an error message when the uer has a +// reasonable expectation for the link to work, but it will fail. +class LLToolsEnableLink : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = false; + // check if there are at least 2 objects selected, and that the + // user can modify at least one of the selected objects. + + // in component mode, can't link + if (gSavedSettings.getBOOL("SelectLinkedSet")) + { + if(gSelectMgr->selectGetAllRootsValid() && gSelectMgr->getRootObjectCount() >= 2) + { + for(LLViewerObject* object = gSelectMgr->getFirstRootObject(); + object != NULL; + object = gSelectMgr->getNextRootObject()) + { + if(object->permModify()) + { + new_value = true; + break; + } + } + } + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLToolsLink : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if(!gSelectMgr->selectGetAllRootsValid()) + { + LLNotifyBox::showXml("UnableToLinkWhileDownloading"); + return true; + } + + S32 object_count = gSelectMgr->getObjectCount(); + if (object_count > MAX_CHILDREN_PER_TASK + 1) + { + LLStringBase<char>::format_map_t args; + args["[COUNT]"] = llformat("%d", object_count); + int max = MAX_CHILDREN_PER_TASK+1; + args["[MAX]"] = llformat("%d", max); + gViewerWindow->alertXml("UnableToLinkObjects", args); + return true; + } + + if(gSelectMgr->getRootObjectCount() < 2) + { + gViewerWindow->alertXml("CannotLinkIncompleteSet"); + return true; + } + if(!gSelectMgr->selectGetRootsModify()) + { + gViewerWindow->alertXml("CannotLinkModify"); + return true; + } + LLUUID owner_id; + LLString owner_name; + if(!gSelectMgr->selectGetOwner(owner_id, owner_name)) + { + // we don't actually care if you're the owner, but novices are + // the most likely to be stumped by this one, so offer the + // easiest and most likely solution. + gViewerWindow->alertXml("CannotLinkDifferentOwners"); + return true; + } + gSelectMgr->sendLink(); + return true; + } +}; + +class LLToolsEnableUnlink : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gSelectMgr->selectGetAllRootsValid() && + gSelectMgr->getFirstEditableObject() && + !gSelectMgr->getFirstEditableObject()->isAttachment(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLToolsUnlink : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + gSelectMgr->sendDelink(); + return true; + } +}; + + +class LLToolsStopAllAnimations : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLVOAvatar* avatarp = gAgent.getAvatarObject(); + + if (!avatarp) return true; + + LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.begin(); + for (;anim_it != avatarp->mAnimationSources.end(); ++anim_it) + { + avatarp->stopMotion( anim_it->second, TRUE ); + } + + avatarp->processAnimationStateChanges(); + return true; + } +}; + +void handle_hinge(void*) +{ + gSelectMgr->sendHinge(1); +} + +void handle_ptop(void*) +{ + gSelectMgr->sendHinge(2); +} + +void handle_lptop(void*) +{ + gSelectMgr->sendHinge(3); +} + +void handle_wheel(void*) +{ + gSelectMgr->sendHinge(4); +} + +void handle_dehinge(void*) +{ + gSelectMgr->sendDehinge(); +} + +BOOL enable_dehinge(void*) +{ + LLViewerObject* obj = gSelectMgr->getFirstEditableObject(); + return obj && !obj->isAttachment(); +} + + +class LLEditEnableCut : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gEditMenuHandler && gEditMenuHandler->canCut(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLEditCut : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if( gEditMenuHandler ) + { + gEditMenuHandler->cut(); + } + return true; + } +}; + +class LLEditEnableCopy : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gEditMenuHandler && gEditMenuHandler->canCopy(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLEditCopy : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if( gEditMenuHandler ) + { + gEditMenuHandler->copy(); + } + return true; + } +}; + +class LLEditEnablePaste : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gEditMenuHandler && gEditMenuHandler->canPaste(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLEditPaste : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if( gEditMenuHandler ) + { + gEditMenuHandler->paste(); + } + return true; + } +}; + +class LLEditEnableDelete : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gEditMenuHandler && gEditMenuHandler->canDoDelete(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLEditDelete : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + // If a text field can do a deletion, it gets precedence over deleting + // an object in the world. + if( gEditMenuHandler && gEditMenuHandler->canDoDelete()) + { + 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 + gPieObject->hide(TRUE); + return true; + } +}; + +class LLObjectEnableDelete : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = +#ifdef HACKED_GODLIKE_VIEWER + TRUE; +#else +# ifdef TOGGLE_HACKED_GODLIKE_VIEWER + (!gInProductionGrid && gAgent.isGodlike()) || +# endif + (gSelectMgr && gSelectMgr->canDoDelete()); +#endif + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLEditSearch : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLFloaterDirectory::toggleFind(NULL); + return true; + } +}; + +class LLObjectDelete : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if (gSelectMgr) + { + gSelectMgr->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 + gPieObject->hide(TRUE); + return true; + } +}; + +void handle_force_delete(void*) +{ + gSelectMgr->selectForceDelete(); +} + +class LLViewEnableLastChatter : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + //FIXME: add check that last chatter is in range + bool new_value = (gAgent.cameraThirdPerson() && gAgent.getLastChatter().notNull()); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLEditEnableDeselect : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gEditMenuHandler && gEditMenuHandler->canDeselect(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLEditDeselect : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if( gEditMenuHandler ) + { + gEditMenuHandler->deselect(); + } + return true; + } +}; + +class LLEditEnableSelectAll : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gEditMenuHandler && gEditMenuHandler->canSelectAll(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + + +class LLEditSelectAll : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if( gEditMenuHandler ) + { + gEditMenuHandler->selectAll(); + } + return true; + } +}; + + +class LLEditEnableUndo : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gEditMenuHandler && gEditMenuHandler->canUndo(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLEditUndo : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if( gEditMenuHandler && gEditMenuHandler->canUndo() ) + { + gEditMenuHandler->undo(); + } + return true; + } +}; + +class LLEditEnableRedo : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gEditMenuHandler && gEditMenuHandler->canRedo(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLEditRedo : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if( gEditMenuHandler && gEditMenuHandler->canRedo() ) + { + gEditMenuHandler->redo(); + } + return true; + } +}; + + + +void print_object_info(void*) +{ + gSelectMgr->selectionDump(); +} + + +void show_debug_menus() +{ + // this can get called at login screen where there is no menu so only toggle it if one exists + if ( gMenuBarView ) + { + BOOL debug = gSavedSettings.getBOOL("UseDebugMenus"); + gMenuBarView->setItemVisible(CLIENT_MENU_NAME, debug); + gMenuBarView->setItemEnabled(CLIENT_MENU_NAME, debug); + gMenuBarView->setItemVisible(SERVER_MENU_NAME, debug); + gMenuBarView->setItemEnabled(SERVER_MENU_NAME, debug); + //gMenuBarView->setItemVisible(LLString("DebugOptions"), visible); + //gMenuBarView->setItemVisible(LLString(AVI_TOOLS), visible); + }; +} + +void toggle_debug_menus(void*) +{ + BOOL visible = ! gSavedSettings.getBOOL("UseDebugMenus"); + gSavedSettings.setBOOL("UseDebugMenus", visible); + show_debug_menus(); +} + + +void toggle_map( void* user_data ) +{ + // Toggle the item + BOOL checked = gSavedSettings.getBOOL( static_cast<char*>(user_data) ); + gSavedSettings.setBOOL( static_cast<char*>(user_data), !checked ); + if (checked) + { + gFloaterMap->close(); + } + else + { + gFloaterMap->open(); + } +} + +/** + char* upload_pick(void* data) + + If applicable, brings up a file chooser in which the user selects a file + to upload for a particular task. If the file is valid for the given action, + returns the string to the full path filename, else returns NULL. + Data is the load filter for the type of file as defined in LLFilePicker. +**/ +const char* upload_pick(void* data) +{ + if( gAgent.cameraMouselook() ) + { + gAgent.changeCameraToDefault(); + // This doesn't seem necessary. JC + // display(); + } + + LLFilePicker::ELoadFilter type; + if(data) + { + type = (LLFilePicker::ELoadFilter)((S32)data); + } + else + { + type = LLFilePicker::FFLOAD_ALL; + } + + LLFilePicker& picker = LLFilePicker::instance(); + if (!picker.getOpenFile(type)) + { + llinfos << "Couldn't import objects from file" << llendl; + return NULL; + } + + const char* filename = picker.getFirstFile(); + const char* ext = strrchr(filename, '.'); + + //strincmp doesn't like NULL pointers + if (ext == NULL) + { + const char* short_name = strrchr(filename, + *gDirUtilp->getDirDelimiter().c_str()); + + // No extension + LLStringBase<char>::format_map_t args; + args["[FILE]"] = LLString(short_name + 1); + gViewerWindow->alertXml("NoFileExtension", args); + return NULL; + } + else + { + //so there is an extension + //loop over the valid extensions and compare to see + //if the extension is valid + + //now grab the set of valid file extensions + const char* valids = build_extensions_string(type); + std::string valid_extensions = std::string(valids); + + BOOL ext_valid = FALSE; + + typedef boost::tokenizer<boost::char_separator<char> > tokenizer; + boost::char_separator<char> sep(" "); + tokenizer tokens(valid_extensions, sep); + tokenizer::iterator token_iter; + + //now loop over all valid file extensions + //and compare them to the extension of the file + //to be uploaded + for( token_iter = tokens.begin(); + token_iter != tokens.end() && ext_valid != TRUE; + ++token_iter) + { + const char* cur_token = token_iter->c_str(); + + if (0 == strnicmp(cur_token, ext, strlen(cur_token)) || + 0 == strnicmp(cur_token, "*.*", strlen(cur_token))) + { + //valid extension + //or the acceptable extension is any + ext_valid = TRUE; + } + }//end for (loop over all tokens) + + if (ext_valid == FALSE) + { + //should only get here if the extension exists + //but is invalid + LLStringBase<char>::format_map_t args; + args["[EXTENSION]"] = ext; + args["[VALIDS]"] = valids; + gViewerWindow->alertXml("InvalidFileExtension", args); + return NULL; + } + }//end else (non-null extension) + + //valid file extension + + //now we check to see + //if the file is actually a valid image/sound/etc. + if (type == LLFilePicker::FFLOAD_WAV) + { + // pre-qualify wavs to make sure the format is acceptable + char error_msg[MAX_STRING]; + if (check_for_invalid_wav_formats(filename,error_msg)) + { + llinfos << error_msg << ": " << filename << llendl; + LLStringBase<char>::format_map_t args; + args["[FILE]"] = filename; + gViewerWindow->alertXml( error_msg, args ); + return NULL; + } + }//end if a wave/sound file + + + return filename; +} + +void handle_upload_object(void* data) +{ + const char* filename = upload_pick(data); + if (filename) + { + // start the import + LLFloaterImport* floaterp = new LLFloaterImport(filename); + gUICtrlFactory->buildFloater(floaterp, "floater_import.xml"); + } +} + +class LLFileUploadImage : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + const char* filename = upload_pick((void *)(S32)LLFilePicker::FFLOAD_IMAGE); + if (filename) + { + LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename); + gUICtrlFactory->buildFloater(floaterp, "floater_image_preview.xml"); + } + return TRUE; + } +}; + +class LLFileUploadSound : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_WAV)); + if (filename) + { + LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename); + gUICtrlFactory->buildFloater(floaterp, "floater_sound_preview.xml"); + } + return true; + } +}; + +class LLFileUploadAnim : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_ANIM)); + if (filename) + { + LLFloaterAnimPreview* floaterp = new LLFloaterAnimPreview(filename); + gUICtrlFactory->buildFloater(floaterp, "floater_animation_preview.xml"); + } + return true; + } +}; + +class LLFileUploadBulk : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if( gAgent.cameraMouselook() ) + { + gAgent.changeCameraToDefault(); + } + + // TODO: + // Iterate over all files + // Check extensions for uploadability, cost + // Check user balance for entire cost + // Charge user entire cost + // Loop, uploading + // If an upload fails, refund the user for that one + // + // Also fix single upload to charge first, then refund + + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getMultipleOpenFiles()) + { + const char* filename = picker.getFirstFile(); + const char* name = picker.getDirname(); + + LLString asset_name = name; + LLString::replaceNonstandardASCII( asset_name, '?' ); + LLString::replaceChar(asset_name, '|', '?'); + LLString::stripNonprintable(asset_name); + LLString::trim(asset_name); + + char* asset_name_str = (char*)asset_name.c_str(); + char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists + if( !end_p ) + { + end_p = asset_name_str + strlen( asset_name_str ); + } + + S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) ); + + asset_name = asset_name.substr( 0, len ); + + upload_new_resource(filename, asset_name, asset_name, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); // file + } + else + { + llinfos << "Couldn't import objects from file" << llendl; + } + return true; + } +}; + +void upload_error(const char* error_message, const char* label, const std::string filename, const LLStringBase<char>::format_map_t args) +{ + llwarns << error_message << llendl; + gViewerWindow->alertXml(label, args); + if(remove(filename.c_str()) == -1) + { + lldebugs << "unable to remove temp file" << llendl; + } + LLFilePicker::instance().reset(); +} + +class LLFileCloseWindow : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLFloater *top = gFloaterView->getFrontmost(); + if (top && top->hasFocus()) + { + LLFloater::closeByMenu( top ); + } + return true; + } +}; + +class LLFileSaveTexture : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLFloater* top = gFloaterView->getFrontmost(); + if (top) + { + top->saveAs(); + } + return true; + } +}; + +class LLFileTakeSnapshot : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLFloaterSnapshot::show(NULL); + return true; + } +}; + +class LLFileTakeSnapshotToDisk : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLPointer<LLImageRaw> raw = new LLImageRaw; + + S32 width = gViewerWindow->getWindowDisplayWidth(); + S32 height = gViewerWindow->getWindowDisplayHeight(); + + if (gSavedSettings.getBOOL("HighResSnapshot")) + { + width *= 2; + height *= 2; + } + + if (gViewerWindow->rawSnapshot(raw, + width, + height, + TRUE, + gSavedSettings.getBOOL("RenderUIInSnapshot"), + FALSE)) + { + if (!gQuietSnapshot) + { + gViewerWindow->playSnapshotAnimAndSound(); + } + LLImageBase::setSizeOverride(TRUE); + gViewerWindow->saveImageNumbered(raw); + LLImageBase::setSizeOverride(FALSE); + } + return true; + } +}; + +class LLFileSaveMovie : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLViewerWindow::saveMovieNumbered(NULL); + return true; + } +}; + +class LLFileSetWindowSize : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString size = userdata.asString(); + S32 width, height; + sscanf(size.c_str(), "%d,%d", &width, &height); + LLViewerWindow::movieSize(width, height); + return true; + } +}; + +class LLFileQuit : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + app_request_quit(); + return true; + } +}; + +void handle_upload(void* data) +{ + const char* filename = upload_pick(data); + if (filename) + { + LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename); + gUICtrlFactory->buildFloater(floaterp, "floater_name_description.xml"); + } +} + +void handle_compress_image(void*) +{ + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE)) + { + std::string infile(picker.getFirstFile()); + std::string outfile = infile + ".j2c"; + + llinfos << "Input: " << infile << llendl; + llinfos << "Output: " << outfile << llendl; + + BOOL success; + + success = LLViewerImageList::createUploadFile(infile, outfile, IMG_CODEC_TGA); + + if (success) + { + llinfos << "Compression complete" << llendl; + } + else + { + llinfos << "Compression failed: " << LLImageBase::getLastError() << llendl; + } + } +} + +void upload_new_resource(const LLString& src_filename, std::string name, + std::string desc, S32 compression_info, + LLAssetType::EType destination_folder_type, + LLInventoryType::EType inv_type, + U32 next_owner_perm, + const LLString& display_name, + LLAssetStorage::LLStoreAssetCallback callback, + void *userdata) +{ + // Generate the temporary UUID. + LLString filename = gDirUtilp->getTempFilename(); + LLTransactionID tid; + LLAssetID uuid; + + LLStringBase<char>::format_map_t args; + + LLString ext = src_filename.substr(src_filename.find_last_of('.')); + LLAssetType::EType asset_type = LLAssetType::AT_NONE; + char error_message[MAX_STRING]; + error_message[0] = '\0'; + LLString temp_str; + + BOOL error = FALSE; + + if (ext.empty()) + { + LLString::size_type offset = filename.find_last_of(gDirUtilp->getDirDelimiter()); + if (offset != LLString::npos) + offset++; + LLString short_name = filename.substr(offset); + + // No extension + sprintf(error_message, + "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension", + short_name.c_str()); + args["[FILE]"] = short_name; + upload_error(error_message, "NofileExtension", filename, args); + return; + } + else if( LLString::compareInsensitive(ext.c_str(),".bmp") == 0 ) + { + asset_type = LLAssetType::AT_TEXTURE; + if (!LLViewerImageList::createUploadFile(src_filename, + filename, + IMG_CODEC_BMP )) + { + sprintf(error_message, "Problem with file %s:\n\n%s\n", + src_filename.c_str(), LLImageBase::getLastError().c_str()); + args["[FILE]"] = src_filename; + args["[ERROR]"] = LLImageBase::getLastError(); + upload_error(error_message, "ProblemWithFile", filename, args); + return; + } + } + else if( LLString::compareInsensitive(ext.c_str(),".tga") == 0 ) + { + asset_type = LLAssetType::AT_TEXTURE; + if (!LLViewerImageList::createUploadFile(src_filename, + filename, + IMG_CODEC_TGA )) + { + sprintf(error_message, "Problem with file %s:\n\n%s\n", + src_filename.c_str(), LLImageBase::getLastError().c_str()); + args["[FILE]"] = src_filename; + args["[ERROR]"] = LLImageBase::getLastError(); + upload_error(error_message, "ProblemWithFile", filename, args); + return; + } + } + else if( LLString::compareInsensitive(ext.c_str(),".jpg") == 0 || LLString::compareInsensitive(ext.c_str(),".jpeg") == 0) + { + asset_type = LLAssetType::AT_TEXTURE; + if (!LLViewerImageList::createUploadFile(src_filename, + filename, + IMG_CODEC_JPEG )) + { + sprintf(error_message, "Problem with file %s:\n\n%s\n", + src_filename.c_str(), LLImageBase::getLastError().c_str()); + args["[FILE]"] = src_filename; + args["[ERROR]"] = LLImageBase::getLastError(); + upload_error(error_message, "ProblemWithFile", filename, args); + return; + } + } + else if(LLString::compareInsensitive(ext.c_str(),".wav") == 0) + { + asset_type = LLAssetType::AT_SOUND; // tag it as audio + S32 encode_result = 0; + + S32 bitrate = 128; + + if (compression_info) + { + bitrate = compression_info; + } + llinfos << "Attempting to encode wav as an ogg file at " << bitrate << "kbps" << llendl; + + encode_result = encode_vorbis_file_at(src_filename.c_str(), filename.c_str(), bitrate*1000); + + if (LLVORBISENC_NOERR != encode_result) + { + switch(encode_result) + { + case LLVORBISENC_DEST_OPEN_ERR: + sprintf(error_message, "Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str()); + args["[FILE]"] = filename; + upload_error(error_message, "CannotOpenTemporarySoundFile", filename, args); + break; + + default: + sprintf(error_message, "Unknown vorbis encode failure on: %s\n", src_filename.c_str()); + args["[FILE]"] = src_filename; + upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args); + break; + } + return; + } + } + else if(LLString::compareInsensitive(ext.c_str(),".tmp") == 0) + { + // This is a generic .lin resource file + asset_type = LLAssetType::AT_OBJECT; + FILE *in = LLFile::fopen(src_filename.c_str(), "rb"); + if (in) + { + // read in the file header + char buf[16384]; + S32 read; + S32 version; + if (fscanf(in, "LindenResource\nversion %d\n", &version)) + { + if (2 == version) + { + char label[MAX_STRING]; + char value[MAX_STRING]; + S32 tokens_read; + while (fgets(buf, 1024, in)) + { + label[0] = '\0'; + value[0] = '\0'; + tokens_read = sscanf(buf, "%s %s\n", label, value); + + llinfos << "got: " << label << " = " << value + << llendl; + + if (EOF == tokens_read) + { + fclose(in); + sprintf(error_message, "corrupt resource file: %s", src_filename.c_str()); + args["[FILE]"] = src_filename; + upload_error(error_message, "CorruptResourceFile", filename, args); + return; + } + + if (2 == tokens_read) + { + if (! strcmp("type", label)) + { + asset_type = (LLAssetType::EType)(atoi(value)); + } + } + else + { + if (! strcmp("_DATA_", label)) + { + // below is the data section + break; + } + } + // other values are currently discarded + } + + } + else + { + fclose(in); + sprintf(error_message, "unknown linden resource file version in file: %s", src_filename.c_str()); + args["[FILE]"] = src_filename; + upload_error(error_message, "UnknownResourceFileVersion", filename, args); + return; + } + } + else + { + // this is an original binary formatted .lin file + // start over at the beginning of the file + fseek(in, 0, SEEK_SET); + + const S32 MAX_ASSET_DESCRIPTION_LENGTH = 256; + const S32 MAX_ASSET_NAME_LENGTH = 64; + S32 header_size = 34 + MAX_ASSET_DESCRIPTION_LENGTH + MAX_ASSET_NAME_LENGTH; + S16 type_num; + + // read in and throw out most of the header except for the type + fread(buf, header_size, 1, in); + memcpy(&type_num, buf + 16, sizeof(S16)); + asset_type = (LLAssetType::EType)type_num; + } + + // copy the file's data segment into another file for uploading + FILE *out = LLFile::fopen(filename.c_str(), "wb"); + if (out) + { + while((read = fread(buf, 1, 16384, in))) + { + fwrite(buf, 1, read, out); + } + fclose(out); + } + else + { + fclose(in); + sprintf(error_message, "Unable to create output file: %s", filename.c_str()); + args["[FILE]"] = filename; + upload_error(error_message, "UnableToCreateOutputFile", filename, args); + return; + } + + fclose(in); + } + else + { + llinfos << "Couldn't open .lin file " << src_filename << llendl; + } + } + else if (LLString::compareInsensitive(ext.c_str(),".bvh") == 0) + { + sprintf(error_message, "We do not currently support bulk upload of animation files\n"); + upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args); + return; + } + else + { + // Unknown extension + sprintf(error_message, "Unknown file extension %s\nExpected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh", ext.c_str()); + error = TRUE;; + } + + // gen a new transaction ID for this asset + tid.generate(); + + if (!error) + { + uuid = tid.makeAssetID(gAgent.getSecureSessionID()); + // copy this file into the vfs for upload + S32 file_size; + apr_file_t* fp = ll_apr_file_open(filename, LL_APR_RB, &file_size); + if (fp) + { + LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE); + + file.setMaxSize(file_size); + + const S32 buf_size = 65536; + U8 copy_buf[buf_size]; + while ((file_size = ll_apr_file_read(fp, copy_buf, buf_size))) + { + file.write(copy_buf, file_size); + } + apr_file_close(fp); + } + else + { + sprintf(error_message, "Unable to access output file: %s", filename.c_str()); + error = TRUE; + } + } + + if (!error) + { + LLString t_disp_name = display_name; + if (t_disp_name.empty()) + { + t_disp_name = src_filename; + } + upload_new_resource(tid, asset_type, name, desc, compression_info, // tid + destination_folder_type, inv_type, next_owner_perm, + display_name, callback, userdata); + } + else + { + llwarns << error_message << llendl; + LLStringBase<char>::format_map_t args; + args["[ERROR_MESSAGE]"] = error_message; + gViewerWindow->alertXml("ErrorMessage", args); + if(LLFile::remove(filename.c_str()) == -1) + { + lldebugs << "unable to remove temp file" << llendl; + } + LLFilePicker::instance().reset(); + } +} + +void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type, + std::string name, + std::string desc, S32 compression_info, + LLAssetType::EType destination_folder_type, + LLInventoryType::EType inv_type, + U32 next_owner_perm, + const LLString& display_name, + LLAssetStorage::LLStoreAssetCallback callback, + void *userdata) +{ + LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID()); + + if( LLAssetType::AT_SOUND == asset_type ) + { + gViewerStats->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT ); + } + else + if( LLAssetType::AT_TEXTURE == asset_type ) + { + gViewerStats->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT ); + } + else + if( LLAssetType::AT_ANIMATION == asset_type) + { + gViewerStats->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT ); + } + + if(LLInventoryType::IT_NONE == inv_type) + { + inv_type = LLInventoryType::defaultForAssetType(asset_type); + } + LLString::stripNonprintable(name); + LLString::stripNonprintable(desc); + if(name.empty()) + { + name = "(No Name)"; + } + if(desc.empty()) + { + desc = "(No Description)"; + } + + // At this point, we're ready for the upload. + LLString upload_message = "Uploading...\n\n"; + upload_message.append(display_name); + LLUploadDialog::modalUploadDialog(upload_message); + + llinfos << "*** Uploading: " << llendl; + llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl; + llinfos << "UUID: " << uuid << llendl; + llinfos << "Name: " << name << llendl; + llinfos << "Desc: " << desc << llendl; + lldebugs << "Folder: " << gInventory.findCategoryUUIDForType(destination_folder_type) << llendl; + lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl; + std::string url = gAgent.getRegion()->getCapability("NewAgentInventory"); + if (!url.empty()) + { + llinfos << "New Agent Inventory via capability" << llendl; + LLSD body; + body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type); + body["asset_type"] = LLAssetType::lookup(asset_type); + body["inventory_type"] = LLInventoryType::lookup(inv_type); + body["name"] = name; + body["description"] = desc; + + std::ostringstream llsdxml; + LLSDSerialize::toXML(body, llsdxml); + lldebugs << "posting body to capability: " << llsdxml.str() << llendl; + LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(uuid, body)); + } + else + { + llinfos << "NewAgentInventory capability not found, new agent inventory via asset system." << llendl; + // check for adequate funds + // TODO: do this check on the sim + if (LLAssetType::AT_SOUND == asset_type || + LLAssetType::AT_TEXTURE == asset_type || + LLAssetType::AT_ANIMATION == asset_type) + { + S32 upload_cost = gGlobalEconomy->getPriceUpload(); + S32 balance = gStatusBar->getBalance(); + if (balance < upload_cost) + { + // insufficient funds, bail on this upload + LLFloaterBuyCurrency::buyCurrency("Uploading costs", upload_cost); + return; + } + } + + LLResourceData* data = new LLResourceData; + data->mAssetInfo.mTransactionID = tid; + data->mAssetInfo.mUuid = uuid; + data->mAssetInfo.mType = asset_type; + data->mAssetInfo.mCreatorID = gAgentID; + data->mInventoryType = inv_type; + data->mNextOwnerPerm = next_owner_perm; + data->mUserData = userdata; + data->mAssetInfo.setName(name); + data->mAssetInfo.setDescription(desc); + data->mPreferredLocation = destination_folder_type; + + LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback; + if (callback) + { + asset_callback = callback; + } + gAssetStorage->storeAssetData(data->mAssetInfo.mTransactionID, data->mAssetInfo.mType, + asset_callback, + (void*)data, + FALSE); + } +} + +void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result) // StoreAssetData callback (fixed) +{ + LLResourceData* data = (LLResourceData*)user_data; + //LLAssetType::EType pref_loc = data->mPreferredLocation; + BOOL is_balance_sufficient = TRUE; + if(result >= 0) + { + LLAssetType::EType dest_loc = (data->mPreferredLocation == LLAssetType::AT_NONE) ? data->mAssetInfo.mType : data->mPreferredLocation; + + if (LLAssetType::AT_SOUND == data->mAssetInfo.mType || + LLAssetType::AT_TEXTURE == data->mAssetInfo.mType || + LLAssetType::AT_ANIMATION == data->mAssetInfo.mType) + { + // Charge the user for the upload. + LLViewerRegion* region = gAgent.getRegion(); + S32 upload_cost = gGlobalEconomy->getPriceUpload(); + + if(!(can_afford_transaction(upload_cost))) + { + LLFloaterBuyCurrency::buyCurrency( + llformat("Uploading %s costs", + data->mAssetInfo.getName().c_str()), + upload_cost); + is_balance_sufficient = FALSE; + } + else if(region) + { + // Charge user for upload + gStatusBar->debitBalance(upload_cost); + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_MoneyTransferRequest); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->nextBlockFast(_PREHASH_MoneyData); + msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_DestID, LLUUID::null); + msg->addU8("Flags", 0); + msg->addS32Fast(_PREHASH_Amount, upload_cost); + msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY); + msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY); + msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE); + msg->addStringFast(_PREHASH_Description, NULL); + msg->sendReliable(region->getHost()); + } + } + + if(is_balance_sufficient) + { + // Actually add the upload to inventory + llinfos << "Adding " << uuid << " to inventory." << llendl; + LLUUID folder_id(gInventory.findCategoryUUIDForType(dest_loc)); + if(folder_id.notNull()) + { + U32 next_owner_perm = data->mNextOwnerPerm; + if(PERM_NONE == next_owner_perm) + { + next_owner_perm = PERM_MOVE | PERM_TRANSFER; + } + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(), + data->mAssetInfo.getDescription(), data->mAssetInfo.mType, + data->mInventoryType, NOT_WEARABLE, next_owner_perm, + LLPointer<LLInventoryCallback>(NULL)); + } + else + { + llwarns << "Can't find a folder to put it in" << llendl; + } + } + } + else // if(result >= 0) + { + LLStringBase<char>::format_map_t args; + args["[FILE]"] = LLInventoryType::lookupHumanReadable(data->mInventoryType); + args["[REASON]"] = LLString(LLAssetStorage::getErrorString(result)); + gViewerWindow->alertXml("CannotUploadReason", args); + } + + LLUploadDialog::modalUploadFinished(); + delete data; + + // *FIX: This is a pretty big hack. What this does is check the + // file picker if there are any more pending uploads. If so, + // upload that file. + const char* next_file = LLFilePicker::instance().getNextFile(); + if(is_balance_sufficient && next_file) + { + const char* name = LLFilePicker::instance().getDirname(); + + LLString asset_name = name; + LLString::replaceNonstandardASCII( asset_name, '?' ); + LLString::replaceChar(asset_name, '|', '?'); + LLString::stripNonprintable(asset_name); + LLString::trim(asset_name); + + char* asset_name_str = (char*)asset_name.c_str(); + char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists + if( !end_p ) + { + end_p = asset_name_str + strlen( asset_name_str ); + } + + S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) ); + + asset_name = asset_name.substr( 0, len ); + + upload_new_resource(next_file, asset_name, asset_name, // file + 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); + } +} + +LLUUID gExporterRequestID; +LLString gExportDirectory; + +LLUploadDialog *gExportDialog = NULL; + +void handle_export_selected( void * ) +{ + if (gSelectMgr->isEmpty()) + { + return; + } + llinfos << "Exporting selected objects:" << llendl; + LLViewerObject *object = gSelectMgr->getFirstRootObject(); + + gExporterRequestID.generate(); + gExportDirectory = ""; + + LLMessageSystem* msg = gMessageSystem; + msg->newMessageFast(_PREHASH_ObjectExportSelected); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_RequestID, gExporterRequestID); + msg->addS16Fast(_PREHASH_VolumeDetail, 4); + + for (; object != NULL; object = gSelectMgr->getNextRootObject()) + { + msg->nextBlockFast(_PREHASH_ObjectData); + msg->addUUIDFast(_PREHASH_ObjectID, object->getID()); + llinfos << "Object: " << object->getID() << llendl; + } + msg->sendReliable(gAgent.getRegion()->getHost()); + + gExportDialog = LLUploadDialog::modalUploadDialog("Exporting selected objects..."); +} + +BOOL menu_check_build_tool( void* user_data ) +{ + S32 index = (S32) user_data; + return gCurrentToolset->isToolSelected( index ); +} + +void handle_reload_settings(void*) +{ + gSavedSettings.resetToDefaults(); + gSavedSettings.loadFromFile(gSettingsFileName, TRUE); + + llinfos << "Loading colors from colors.xml" << llendl; + std::string color_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"colors.xml"); + gColors.resetToDefaults(); + gColors.loadFromFile(color_file, FALSE, TYPE_COL4U); +} + +class LLWorldSetHomeLocation : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, 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 LLWorldTeleportHome : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + gAgent.teleportHome(); + return true; + } +}; + +class LLWorldAlwaysRun : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if (gAgent.getAlwaysRun()) + { + gAgent.clearAlwaysRun(); + } + else + { + gAgent.setAlwaysRun(); + } + LLMessageSystem *msg = gMessageSystem; + + + msg->newMessageFast(_PREHASH_SetAlwaysRun); + msg->nextBlockFast(_PREHASH_AgentData); + msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); + msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + msg->addBOOLFast(_PREHASH_AlwaysRun, gAgent.getAlwaysRun() ); + gAgent.sendReliableMessage(); + return true; + } +}; + +class LLWorldCheckAlwaysRun : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gAgent.getAlwaysRun(); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLWorldSetAway : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if (gAgent.getAFK()) + { + gAgent.clearAFK(); + } + else + { + gAgent.setAFK(); + } + return true; + } +}; + +class LLWorldSetBusy : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if (gAgent.getBusy()) + { + gAgent.clearBusy(); + } + else + { + gAgent.setBusy(); + gViewerWindow->alertXml("BusyModeSet"); + } + return true; + } +}; + + +class LLWorldCreateLandmark : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLViewerRegion* agent_region = gAgent.getRegion(); + if(!agent_region) + { + llwarns << "No agent region" << llendl; + return true; + } + LLParcel* agent_parcel = gParcelMgr->getAgentParcel(); + if (!agent_parcel) + { + llwarns << "No agent parcel" << llendl; + return true; + } + if (!agent_parcel->getAllowLandmark() + && !LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK)) + { + gViewerWindow->alertXml("CannotCreateLandmarkNotOwner"); + return true; + } + + LLUUID folder_id; + folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK); + std::string pos_string; + gAgent.buildLocationString(pos_string); + + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), + folder_id, LLTransactionID::tnull, + pos_string, pos_string, // name, desc + LLAssetType::AT_LANDMARK, + LLInventoryType::IT_LANDMARK, + NOT_WEARABLE, PERM_ALL, + NULL); + return true; + } +}; + +class LLToolsLookAtSelection : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + const F32 PADDING_FACTOR = 2.f; + BOOL zoom = (userdata.asString() == "zoom"); + if (!gSelectMgr->isEmpty()) + { + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + + LLBBox selection_bbox = gSelectMgr->getBBoxOfSelection(); + F32 angle_of_view = llmax(0.1f, gCamera->getAspect() > 1.f ? gCamera->getView() * gCamera->getAspect() : gCamera->getView()); + F32 distance = selection_bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view); + + LLVector3 obj_to_cam = gCamera->getOrigin() - selection_bbox.getCenterAgent(); + obj_to_cam.normVec(); + + if (zoom) + { + gAgent.setCameraPosAndFocusGlobal(gSelectMgr->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance), gSelectMgr->getSelectionCenterGlobal(), gSelectMgr->getFirstObject()->mID ); + } + else + { + gAgent.setFocusGlobal( gSelectMgr->getSelectionCenterGlobal(), gSelectMgr->getFirstObject()->mID ); + } + } + return true; + } +}; + +/* +void handle_reset_rotation(void*) +{ + gSelectMgr->selectionResetRotation(); + + dialog_refresh_all(); +} +*/ + +class LLAvatarAddFriend : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); + if(avatar && !is_agent_friend(avatar->getID())) + { + request_friendship(avatar->getID()); + } + gSelectMgr->deselectTransient(); + return true; + } +}; + +void complete_give_money(S32 option, void* user_data) +{ + if (option == 0) + { + gAgent.clearBusy(); + } + + LLUUID* object_id = (LLUUID*)user_data; + + LLViewerObject* object = gObjectList.findObject(*object_id); + if (object) + { + if (object->isAvatar()) + { + const BOOL is_group = FALSE; + LLFloaterPay::payDirectly(&give_money, + *object_id, + is_group); + } + else + { + LLFloaterPay::payViaObject(&give_money, *object_id); + } + } + + delete object_id; +} + +bool handle_give_money_dialog() +{ + LLViewerObject *objectp = gViewerWindow->lastObjectHit(); + LLUUID* object_id = new LLUUID(); + + // Show avatar's name if paying attachment + if (objectp && objectp->isAttachment()) + { + while (objectp && !objectp->isAvatar()) + { + objectp = (LLViewerObject*)objectp->getParent(); + } + } + + if (objectp) + { + *object_id = objectp->getID(); + } + + if (gAgent.getBusy()) + { + // warn users of being in busy mode during a transaction + gViewerWindow->alertXml("BusyModePay", complete_give_money, object_id); + } + else + { + complete_give_money(1, object_id); + } + return true; +} + +class LLPayObject : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + return handle_give_money_dialog(); + } +}; + +class LLEnablePayObject : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object(gViewerWindow->lastObjectHit()); + bool new_value = (avatar != NULL); + if (!new_value) + { + LLViewerObject* object = gViewerWindow->lastObjectHit(); + if( object ) + { + LLViewerObject *parent = (LLViewerObject *)object->getParent(); + if((object->flagTakesMoney()) || (parent && parent->flagTakesMoney())) + { + new_value = true; + } + } + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLObjectEnableSitOrStand : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = false; + LLViewerObject* dest_object = NULL; + if(dest_object = gObjectList.findObject(gLastHitObjectID)) + { + if(dest_object->getPCode() == LL_PCODE_VOLUME) + { + new_value = true; + } + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + + // HACK: Update label + LLString label; + LLString sit_text; + LLString stand_text; + LLString param = userdata["data"].asString(); + LLString::size_type offset = param.find(","); + if (offset != param.npos) + { + sit_text = param.substr(0, offset); + stand_text = param.substr(offset+1); + } + if (sitting_on_selection()) + { + label = stand_text; + } + else + { + LLSelectNode* node = gSelectMgr->getFirstRootNode(); + if (node && node->mValid && !node->mSitName.empty()) + { + label.assign(node->mSitName); + } + else + { + label = sit_text; + } + } + gMenuHolder->childSetText("Object Sit", label); + + return true; + } +}; + +void edit_ui(void*) +{ + LLFloater::setEditModeEnabled(!LLFloater::getEditModeEnabled()); +} + +void dump_select_mgr(void*) +{ + gSelectMgr->dump(); +} + +void dump_volume_mgr(void*) +{ + gVolumeMgr->dump(); +} + +void dump_inventory(void*) +{ + gInventory.dumpInventory(); +} + + +void handle_first_tool(void*) +{ + gCurrentToolset->selectFirstTool(); +} + + +void handle_next_tool(void*) +{ + gCurrentToolset->selectNextTool(); +} + + +void handle_previous_tool(void*) +{ + gCurrentToolset->selectPrevTool(); +} + + +// forcibly unlock an object +void handle_force_unlock(void*) +{ + // First, make it public. + gSelectMgr->sendOwner(LLUUID::null, LLUUID::null, TRUE); + + // Second, lie to the viewer and mark it editable and unowned + LLViewerObject* object; + for (object = gSelectMgr->getFirstObject(); object; object = gSelectMgr->getNextObject() ) + { + object->mFlags |= FLAGS_OBJECT_MOVE; + object->mFlags |= FLAGS_OBJECT_MODIFY; + object->mFlags |= FLAGS_OBJECT_COPY; + + object->mFlags &= ~FLAGS_OBJECT_ANY_OWNER; + object->mFlags &= ~FLAGS_OBJECT_YOU_OWNER; + } +} + +// Fullscreen debug stuff +void handle_fullscreen_debug(void*) +{ + llinfos << "Width " << gViewerWindow->getWindowWidth() << " Height " << gViewerWindow->getWindowHeight() << llendl; + llinfos << "mouse_x_from_center(100) " << mouse_x_from_center(100) << " y " << mouse_y_from_center(100) << llendl; +} + +void handle_crash(void*) +{ + llerrs << "This is an llerror" << llendl; +} + +class LLWorldForceSun : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString tod = userdata.asString(); + LLVector3 sun_direction; + if (tod == "sunrise") + { + sun_direction.setVec(1.0f, 0.f, 0.2f); + } + else if (tod == "noon") + { + sun_direction.setVec(0.0f, 0.3f, 1.0f); + } + else if (tod == "sunset") + { + sun_direction.setVec(-1.0f, 0.f, 0.2f); + } + else if (tod == "midnight") + { + sun_direction.setVec(0.0f, 0.3f, -1.0f); + } + else + { + gSky.setOverrideSun(FALSE); + return true; + } + sun_direction.normVec(); + gSky.setOverrideSun(TRUE); + gSky.setSunDirection( sun_direction, LLVector3(0.f, 0.f, 0.f)); + return true; + } +}; + +void handle_dump_followcam(void*) +{ + LLFollowCamMgr::dump(); +} + +void handle_viewer_enable_circuit_log(void*) +{ + llinfos << "Showing circuit information every " << gMessageSystem->mCircuitPrintFreq << " seconds" << llendl; + gErrorStream.setLevel( LLErrorStream::DEBUG ); + gErrorStream.setDebugFlag( LLERR_CIRCUIT_INFO ); + // and dump stuff out immediately + gMessageSystem->dumpCircuitInfo(); +} + +void handle_viewer_disable_circuit_log(void*) +{ + llinfos << "Hiding circuit information" << llendl; +#if !LL_DEBUG + gErrorStream.setLevel( LLErrorStream::INFO ); +#endif + gErrorStream.clearDebugFlag( LLERR_CIRCUIT_INFO ); +} + +void handle_viewer_enable_message_log(void*) +{ + gMessageSystem->startLogging(); +} + +void handle_viewer_disable_message_log(void*) +{ + gMessageSystem->stopLogging(); +} + +// TomY TODO: Move! +class LLShowFloater : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString floater_name = userdata.asString(); + if (floater_name == "gestures") + { + LLFloaterGesture::toggleVisibility(); + } + else if (floater_name == "appearance") + { + if (gAgent.getWearablesLoaded()) + { + gAgent.changeCameraToCustomizeAvatar(); + } + } + else if (floater_name == "friends") + { + LLFloaterFriends::toggle(NULL); + } + else if (floater_name == "preferences") + { + LLFloaterPreference::show(NULL); + } + else if (floater_name == "toolbar") + { + LLToolBar::toggle(NULL); + } + else if (floater_name == "chat history") + { + LLFloaterChat::toggle(NULL); + } + else if (floater_name == "im") + { + LLToolBar::onClickIM(NULL); + } + else if (floater_name == "inventory") + { + LLInventoryView::toggleVisibility(NULL); + } + else if (floater_name == "mute list") + { + LLFloaterMute::toggle(NULL); + } + else if (floater_name == "camera controls") + { + LLFloaterCamera::toggle(NULL); + } + else if (floater_name == "movement controls") + { + LLFloaterMove::show(NULL); + } + else if (floater_name == "world map") + { + LLFloaterWorldMap::toggle(NULL); + } + else if (floater_name == "mini map") + { + LLFloaterMap::toggle(NULL); + } + else if (floater_name == "stat bar") + { + gDebugView->mStatViewp->setVisible(!gDebugView->mStatViewp->getVisible()); + } + else if (floater_name == "account history") + { + LLFloaterAccountHistory::show(NULL); + } + else if (floater_name == "my land") + { + LLFloaterLandHoldings::show(NULL); + } + else if (floater_name == "about land") + { + if (gParcelMgr->selectionEmpty()) + { + gParcelMgr->selectParcelAt(gAgent.getPositionGlobal()); + } + + LLFloaterLand::show(); + } + else if (floater_name == "buy land") + { + if (gParcelMgr->selectionEmpty()) + { + gParcelMgr->selectParcelAt(gAgent.getPositionGlobal()); + } + + gParcelMgr->startBuyLand(); + } + else if (floater_name == "about region") + { + LLFloaterRegionInfo::show((void *)NULL); + } + else if (floater_name == "grid options") + { + LLFloaterBuildOptions::show(NULL); + } + else if (floater_name == "script errors") + { + LLFloaterScriptDebug::show(LLUUID::null); + } + else if (floater_name == "help") + { +#if LL_LIBXUL_ENABLED + LLHtmlHelp::show(NULL); +#endif + } + else if (floater_name == "complaint reporter") + { + // Prevent menu from appearing in screen shot. + gMenuHolder->hideMenus(); + LLFloaterReporter::showFromMenu(COMPLAINT_REPORT); + } + else if (floater_name == "mean events") + { + if (!gNoRender) + { + LLFloaterBump::show(NULL); + } + } + else if (floater_name == "bug reporter") + { + // Prevent menu from appearing in screen shot. + gMenuHolder->hideMenus(); + LLFloaterReporter::showFromMenu(BUG_REPORT); + } + else if (floater_name == "buy currency") + { + LLFloaterBuyCurrency::buyCurrency(); + } + else if (floater_name == "about") + { + LLFloaterAbout::show(NULL); + } + return true; + } +}; + +class LLFloaterVisible : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString control_name = userdata["control"].asString(); + LLString floater_name = userdata["data"].asString(); + bool new_value = false; + if (floater_name == "friends") + { + new_value = LLFloaterFriends::visible(NULL); + } + else if (floater_name == "toolbar") + { + new_value = LLToolBar::visible(NULL); + } + else if (floater_name == "chat history") + { + new_value = LLFloaterChat::visible(NULL); + } + else if (floater_name == "im") + { + new_value = gIMView && gIMView->mTalkFloater && gIMView->mTalkFloater->getVisible(); + } + else if (floater_name == "mute list") + { + new_value = LLFloaterMute::visible(NULL); + } + else if (floater_name == "camera controls") + { + new_value = LLFloaterCamera::visible(NULL); + } + else if (floater_name == "movement controls") + { + new_value = LLFloaterMove::visible(NULL); + } + else if (floater_name == "stat bar") + { + new_value = gDebugView->mStatViewp->getVisible(); + } + gMenuHolder->findControl(control_name)->setValue(new_value); + return true; + } +}; + +void callback_show_url(S32 option, void* url) +{ + const char* urlp = (const char*)url; + if (0 == option) + { + LLWeb::loadURL(urlp); + } + delete urlp; +} + +class LLPromptShowURL : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString param = userdata.asString(); + LLString::size_type offset = param.find(","); + if (offset != param.npos) + { + LLString alert = param.substr(0, offset); + LLString url = param.substr(offset+1); + char *url_copy = new char[url.size()+1]; + strcpy(url_copy, url.c_str()); + gViewerWindow->alertXml(alert, callback_show_url, url_copy); + } + else + { + llinfos << "PromptShowURL invalid parameters! Expecting \"ALERT,URL\"." << llendl; + } + return true; + } +}; + +void callback_show_file(S32 option, void* filename) +{ + const char* filenamep = (const char*)filename; + if (0 == option) + { + load_url_local_file(filenamep); + } + delete filenamep; +} + +class LLPromptShowFile : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString param = userdata.asString(); + LLString::size_type offset = param.find(","); + if (offset != param.npos) + { + LLString alert = param.substr(0, offset); + LLString file = param.substr(offset+1); + char *file_copy = new char[file.size()+1]; + strcpy(file_copy, file.c_str()); + gViewerWindow->alertXml(alert, callback_show_file, file_copy); + } + else + { + llinfos << "PromptShowFile invalid parameters! Expecting \"ALERT,FILE\"." << llendl; + } + return true; + } +}; + +class LLShowAgentProfile : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLUUID agent_id; + if (userdata.asString() == "agent") + { + agent_id = gAgent.getID(); + } + else if (userdata.asString() == "hit object") + { + agent_id = gLastHitObjectID; + } + else + { + agent_id = userdata.asUUID(); + } + + LLVOAvatar* avatar = find_avatar_from_object(agent_id); + if (avatar) + { + LLFloaterAvatarInfo::showFromAvatar(avatar); + } + return true; + } +}; + +class LLShowAgentGroups : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLUUID agent_id; + if (userdata.asString() == "agent") + { + agent_id = gAgent.getID(); + } + else + { + agent_id = userdata.asUUID(); + } + if(agent_id.notNull()) + { + LLFloaterGroups::show(agent_id, LLFloaterGroups::AGENT_GROUPS); + } + return true; + } +}; + +void handle_focus(void *) +{ + if (gDisconnected) + { + return; + } + + if (gAgent.getFocusOnAvatar()) + { + // zoom in if we're looking at the avatar + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); + gAgent.cameraZoomIn(0.666f); + } + else + { + gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); + } + + gViewerWindow->moveCursorToCenter(); + + // Switch to camera toolset +// gCurrentToolset = gCameraToolset; + gCurrentToolset->selectTool( gToolCamera ); +} + +class LLLandEdit : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + if (gAgent.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") ) + { + // zoom in if we're looking at the avatar + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); + + gAgent.cameraOrbitOver( F_PI * 0.25f ); + gViewerWindow->moveCursorToCenter(); + } + else if ( gSavedSettings.getBOOL("EditCameraMovement") ) + { + gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); + gViewerWindow->moveCursorToCenter(); + } + + + gParcelMgr->selectParcelAt( gLastHitPosGlobal ); + + gFloaterTools->showMore(TRUE); + gFloaterView->bringToFront( gFloaterTools ); + + // Switch to land edit toolset + gCurrentToolset->selectTool( gToolParcel ); + return true; + } +}; + +class LLWorldEnableBuyLand : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gParcelMgr->canAgentBuyParcel( + gParcelMgr->selectionEmpty() + ? gParcelMgr->getAgentParcel() + : gParcelMgr->getSelectedParcel(), + false); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +BOOL enable_buy_land(void*) +{ + return gParcelMgr->canAgentBuyParcel( + gParcelMgr->getSelectedParcel(), false); +} + + +void handle_move(void*) +{ + if (gAgent.getFocusOnAvatar()) + { + // zoom in if we're looking at the avatar + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); + + gAgent.cameraZoomIn(0.666f); + } + else + { + gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID); + } + + gViewerWindow->moveCursorToCenter(); + + gCurrentToolset = gBasicToolset; + gCurrentToolset->selectTool( gToolGrab ); +} + + +void near_attach_object(BOOL success, void *user_data) +{ + LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; + + U8 attachment_id; + if (attachment) + { + attachment_id = gAgent.getAvatarObject()->mAttachmentPoints.reverseLookup(attachment); + } + else + { + // interpret 0 as "default location" + attachment_id = 0; + } + + gSelectMgr->sendAttach(attachment_id); + gSelectMgr->deselectTransient(); +} + +class LLObjectAttachToAvatar : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLViewerObject* selectedObject = gSelectMgr->getFirstRootObject(); + if (selectedObject) + { + confirm_replace_attachment(0, NULL); + } + return true; + } +}; + +// move this somewhere global +void handle_attach_to_avatar(void* user_data) +{ + LLViewerObject* selectedObject = gSelectMgr->getFirstRootObject(); + if (selectedObject) + { + LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; + + if (attachment && attachment->getObject(0)) + { + gViewerWindow->alertXml("ReplaceAttachment", confirm_replace_attachment, user_data); + } + else + { + confirm_replace_attachment(0, user_data); + } + } +} +void confirm_replace_attachment(S32 option, void* user_data) +{ + if (option == 0/*YES*/) + { + LLViewerObject* selectedObject = gSelectMgr->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; + + gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, near_attach_object, user_data, stop_distance); + gAgent.clearFocusObject(); + } + } +} + +class LLAttachmentDrop : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + // Called when the user clicked on an object attached to them + // and selected "Drop". + LLViewerObject *object = gViewerWindow->lastObjectHit(); + if (!object) + { + llwarns << "handle_drop_attachment() - no object to drop" << llendl; + return true; + } + + LLViewerObject *parent = (LLViewerObject*)object->getParent(); + while (parent) + { + if(parent->isAvatar()) + { + break; + } + object = parent; + parent = (LLViewerObject*)parent->getParent(); + } + + if (!object) + { + llwarns << "handle_detach() - no object to detach" << llendl; + return true; + } + + if (object->isAvatar()) + { + llwarns << "Trying to detach avatar from avatar." << llendl; + return true; + } + + // The sendDropAttachment() method works on the list of selected + // objects. Thus we need to clear the list, make sure it only + // contains the object the user clicked, send the message, + // then clear the list. + // We use deselectAll to update the simulator's notion of what's + // selected, and removeAll just to change things locally. + //gSelectMgr->deselectAll(); + //gSelectMgr->selectObjectAndFamily(object); + gSelectMgr->sendDropAttachment(); + gSelectMgr->deselectTransient(); + return true; + } +}; + +// called from avatar pie menu +void handle_detach_from_avatar(void* user_data) +{ + LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; + + LLViewerObject* attached_object = attachment->getObject(0); + + if (attached_object) + { + gMessageSystem->newMessage("ObjectDetach"); + gMessageSystem->nextBlockFast(_PREHASH_AgentData); + gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() ); + gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); + + gMessageSystem->nextBlockFast(_PREHASH_ObjectData); + gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID()); + gMessageSystem->sendReliable( gAgent.getRegionHost() ); + } +} + +void attach_label(LLString& label, void* user_data) +{ + LLViewerJointAttachment* attachmentp = (LLViewerJointAttachment*)user_data; + if (attachmentp) + { + label = attachmentp->getName(); + if (attachmentp->getObject(0)) + { + LLViewerInventoryItem* itemp = gInventory.getItem(attachmentp->getItemID()); + if (itemp) + { + label += LLString(" (") + itemp->getName() + LLString(")"); + } + } + } +} + +void detach_label(LLString& label, void* user_data) +{ + LLViewerJointAttachment* attachmentp = (LLViewerJointAttachment*)user_data; + if (attachmentp) + { + label = attachmentp->getName(); + if (attachmentp->getObject(0)) + { + LLViewerInventoryItem* itemp = gInventory.getItem(attachmentp->getItemID()); + if (itemp) + { + label += LLString(" (") + itemp->getName() + LLString(")"); + } + } + } +} + + +class LLAttachmentDetach : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + // Called when the user clicked on an object attached to them + // and selected "Detach". + LLViewerObject *object = gViewerWindow->lastObjectHit(); + if (!object) + { + llwarns << "handle_detach() - no object to detach" << llendl; + return true; + } + + LLViewerObject *parent = (LLViewerObject*)object->getParent(); + while (parent) + { + if(parent->isAvatar()) + { + break; + } + object = parent; + parent = (LLViewerObject*)parent->getParent(); + } + + if (!object) + { + llwarns << "handle_detach() - no object to detach" << llendl; + return true; + } + + if (object->isAvatar()) + { + llwarns << "Trying to detach avatar from avatar." << llendl; + return true; + } + + // The sendDetach() method works on the list of selected + // objects. Thus we need to clear the list, make sure it only + // contains the object the user clicked, send the message, + // then clear the list. + // We use deselectAll to update the simulator's notion of what's + // selected, and removeAll just to change things locally. + //RN: I thought it was more useful to detach everything that was selected + if (gSelectMgr->selectionIsAttachment()) + { + gSelectMgr->sendDetach(); + gSelectMgr->deselectAll(); + } + return true; + } +}; + +//Adding an observer for a Jira 2422 and needs to be a fetch observer +//for Jira 3119 +class LLWornItemFetchedObserver : public LLInventoryFetchObserver +{ +public: + LLWornItemFetchedObserver() {} + virtual ~LLWornItemFetchedObserver() {} + +protected: + virtual void done() + { + gPieAttachment->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(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLParcel* parcel = gParcelMgr->getAgentParcel(); + BOOL can_build = gAgent.isGodlike() || (parcel && parcel->getAllowModify()); + + //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 = gViewerWindow->lastObjectHit(); + LLViewerJointAttachment* attachment_pt = NULL; + LLInventoryItem* item = NULL; + + if ( object ) + { + S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getState()); + attachment_pt = gAgent.getAvatarObject()->mAttachmentPoints.getIfThere(attachmentID); + + if ( attachment_pt ) + { + // 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_pt->getItemID()); + + 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* wornItemFetched = new LLWornItemFetchedObserver(); + LLInventoryFetchObserver::item_ref_t items; //add item to the inventory item to be fetched + + items.push_back(attachment_pt->getItemID()); + + wornItemFetched->fetchItems(items); + gInventory.addObserver(wornItemFetched); + } + } + } + + //now check to make sure that the item is actually in the inventory before we enable dropping it + bool new_value = enable_detach(NULL) && can_build && item; + + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +BOOL enable_detach(void*) +{ + LLViewerObject* object = gViewerWindow->lastObjectHit(); + if (!object) return FALSE; + if (!object->isAttachment()) 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()) + { + return TRUE; + } + + avatar = (LLViewerObject*)avatar->getParent(); + } + + return FALSE; +} + +class LLAttachmentEnableDetach : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = enable_detach(NULL); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +// Used to tell if the selected object can be attached to your avatar. +BOOL object_selected_and_point_valid(void *user_data) +{ + //LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; + + for (LLViewerObject *object = gSelectMgr->getFirstRootObject(); object; object = gSelectMgr->getNextRootObject()) + { + for (U32 child_num = 0; child_num < object->mChildList.size(); child_num++ ) + { + if (object->mChildList[child_num]->isAvatar()) + { + return FALSE; + } + } + } + + return ((gSelectMgr != NULL) && + (gSelectMgr->getRootObjectCount() == 1) && + (gSelectMgr->getFirstRootObject()->getPCode() == LL_PCODE_VOLUME) && + gSelectMgr->getFirstRootObject()->permYouOwner() && + !((LLViewerObject*)gSelectMgr->getFirstRootObject()->getRoot())->isAvatar() && + (gSelectMgr->getFirstRootObject()->getNVPair("AssetContainer") == NULL)); +} + +// Also for seeing if object can be attached. See above. +class LLObjectEnableWear : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = false; + if (gSelectMgr) + { + LLViewerObject* first_root = gSelectMgr->getFirstRootObject(); + if (first_root) + { + new_value = gSelectMgr->getRootObjectCount() == 1 + && first_root->getPCode() == LL_PCODE_VOLUME + && first_root->permYouOwner() + && !((LLViewerObject*)gSelectMgr->getFirstRootObject()->getRoot())->isAvatar() + && (first_root->getNVPair("AssetContainer") == NULL); + } + } + + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + + +BOOL object_attached(void *user_data) +{ + LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data; + + return attachment->getObject(0) != NULL; +} + +class LLAvatarSendIM : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() ); + if(avatar) + { + LLString name("IM"); + LLNameValue *first = avatar->getNVPair("FirstName"); + LLNameValue *last = avatar->getNVPair("LastName"); + if (first && last) + { + name.assign( first->getString() ); + name.append(" "); + name.append( last->getString() ); + } + + gIMView->setFloaterOpen(TRUE); + //EInstantMessage type = have_agent_callingcard(gLastHitObjectID) + // ? IM_SESSION_ADD : IM_SESSION_CARDLESS_START; + gIMView->addSession(name, + IM_NOTHING_SPECIAL, + avatar->getID()); + } + return true; + } +}; + + +void handle_activate(void*) +{ +} + +BOOL enable_activate(void*) +{ + return FALSE; +} + +class LLToolsSelectedScriptAction : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString action = userdata.asString(); + LLFloaterScriptQueue *queue = NULL; + if (action == "compile") + { + queue = LLFloaterCompileQueue::create(); + } + else if (action == "reset") + { + queue = LLFloaterResetQueue::create(); + } + else if (action == "start") + { + queue = LLFloaterRunQueue::create(); + } + else if (action == "stop") + { + queue = LLFloaterNotRunQueue::create(); + } + if (!queue) return true; + + BOOL scripted = FALSE; + BOOL modifiable = FALSE; + + for(LLViewerObject* obj = gSelectMgr->getFirstObject(); + obj; + obj = gSelectMgr->getNextObject()) + { + scripted = obj->flagScripted(); + modifiable = obj->permModify(); + + if( scripted && modifiable ) + queue->addObject(obj->getID()); + else + break; + } + + if(!queue->start()) + { + if ( ! scripted ) + { + gViewerWindow->alertXml("CannotRecompileSelectObjectsNoScripts"); + } + else if ( ! modifiable ) + { + gViewerWindow->alertXml("CannotRecompileSelectObjectsNoPermission"); + } + } + return true; + } +}; + +void handle_reset_selection(void*) +{ + LLFloaterResetQueue* queue = LLFloaterResetQueue::create(); + + BOOL scripted = FALSE; + BOOL modifiable = FALSE; + + for(LLViewerObject* obj = gSelectMgr->getFirstObject(); + obj; + obj = gSelectMgr->getNextObject()) + { + scripted = obj->flagScripted(); + modifiable = obj->permModify(); + + if( scripted && modifiable ) + queue->addObject(obj->getID()); + else + break; + } + + if(!queue->start()) + { + if ( ! scripted ) + { + gViewerWindow->alertXml("CannotResetSelectObjectsNoScripts"); + } + else if ( ! modifiable ) + { + gViewerWindow->alertXml("CannotResetSelectObjectsNoPermission"); + } + } +} + +void handle_set_run_selection(void*) +{ + LLFloaterRunQueue* queue = LLFloaterRunQueue::create(); + + BOOL scripted = FALSE; + BOOL modifiable = FALSE; + + for(LLViewerObject* obj = gSelectMgr->getFirstObject(); + obj; + obj = gSelectMgr->getNextObject()) + { + scripted = obj->flagScripted(); + modifiable = obj->permModify(); + + if( scripted && modifiable ) + queue->addObject(obj->getID()); + else + break; + } + + if(!queue->start()) + { + if ( ! scripted ) + { + gViewerWindow->alertXml("CannotSetRunningSelectObjectsNoScripts"); + } + else if ( ! modifiable ) + { + gViewerWindow->alertXml("CannotSerRunningSelectObjectsNoPermission"); + } + } +} + +void handle_set_not_run_selection(void*) +{ + LLFloaterNotRunQueue* queue = LLFloaterNotRunQueue::create(); + + BOOL scripted = FALSE; + BOOL modifiable = FALSE; + + for(LLViewerObject* obj = gSelectMgr->getFirstObject(); + obj; + obj = gSelectMgr->getNextObject()) + { + scripted = obj->flagScripted(); + modifiable = obj->permModify(); + + if( scripted && modifiable ) + queue->addObject(obj->getID()); + else + break; + } + + if(!queue->start()) + { + if ( ! scripted ) + { + gViewerWindow->alertXml("CannotSetRunningNotSelectObjectsNoScripts"); + } + else if ( ! modifiable ) + { + gViewerWindow->alertXml("CannotSerRunningNotSelectObjectsNoPermission"); + } + } +} + +void handle_selected_texture_info(void*) +{ + LLSelectNode* node = NULL; + for (node = gSelectMgr->getFirstNode(); node != NULL; node = gSelectMgr->getNextNode()) + { + if (!node->mValid) continue; + + std::string msg; + msg.assign("Texture info for: "); + msg.append(node->mName); + LLChat chat(msg); + LLFloaterChat::addChat(chat); + + 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; + + LLViewerImage* 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) + { + LLUUID image_id = it->first; + U8 te = it->second[0]; + LLViewerImage* img = node->getObject()->getTEImage(te); + S32 height = img->getHeight(); + S32 width = img->getWidth(); + S32 components = img->getComponents(); + std::string image_id_string; + if (gAgent.isGodlike()) + { + image_id_string = image_id.getString() + " "; + } + msg = llformat("%s%dx%d %s on face ", + image_id_string.c_str(), + width, + height, + (components == 4 ? "alpha" : "opaque")); + for (U8 i = 0; i < it->second.size(); ++i) + { + msg.append( llformat("%d ", (S32)(it->second[i]))); + } + LLChat chat(msg); + LLFloaterChat::addChat(chat); + } + } +} + +void handle_dump_image_list(void*) +{ + gImageList.dump(); +} + +void handle_test_male(void*) +{ + wear_outfit_by_name("Male Shape & Outfit"); + //gGestureList.requestResetFromServer( TRUE ); +} + +void handle_test_female(void*) +{ + wear_outfit_by_name("Female Shape & Outfit"); + //gGestureList.requestResetFromServer( FALSE ); +} + +void handle_toggle_pg(void*) +{ + if (gAgent.mAccess < SIM_ACCESS_MATURE) + { + gAgent.mAccess = SIM_ACCESS_MATURE; + } + else + { + gAgent.mAccess = SIM_ACCESS_PG; + } + + LLFloaterWorldMap::reloadIcons(NULL); + + llinfos << "Access set to " << (S32)gAgent.mAccess << llendl; +} + +void handle_dump_attachments(void*) +{ + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if( !avatar ) + { + llinfos << "NO AVATAR" << llendl; + return; + } + + for( LLViewerJointAttachment* attachment = avatar->mAttachmentPoints.getFirstData(); + attachment; + attachment = avatar->mAttachmentPoints.getNextData() ) + { + S32 key = avatar->mAttachmentPoints.getCurrentKeyWithoutIncrement(); + BOOL visible = (attachment->getObject(0) != NULL && + attachment->getObject(0)->mDrawable.notNull() && + !attachment->getObject(0)->mDrawable->isRenderType(0)); + LLVector3 pos; + if (visible) pos = attachment->getObject(0)->mDrawable->getPosition(); + llinfos << "ATTACHMENT " << key << ": item_id=" << attachment->getItemID() + << (attachment->getObject(0) ? " present " : " absent ") + << (visible ? "visible " : "invisible ") + << " at " << pos + << " and " << (visible ? attachment->getObject(0)->getPosition() : LLVector3::zero) + << llendl; + } +} + +//--------------------------------------------------------------------- +// Callbacks for enabling/disabling items +//--------------------------------------------------------------------- + +BOOL menu_ui_enabled(void *user_data) +{ + BOOL high_res = gSavedSettings.getBOOL( "HighResSnapshot" ); + return !high_res; +} + +// TomY TODO DEPRECATE & REMOVE +void menu_toggle_control( void* user_data ) +{ + BOOL checked = gSavedSettings.getBOOL( static_cast<char*>(user_data) ); + if (LLString(static_cast<char*>(user_data)) == "HighResSnapshot" && !checked) + { + // High Res Snapshot active, must uncheck RenderUIInSnapshot + gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE ); + } + gSavedSettings.setBOOL( static_cast<char*>(user_data), !checked ); +} + + +// these are used in the gl menus to set control values. +class LLToggleControl : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString control_name = userdata.asString(); + BOOL checked = gSavedSettings.getBOOL( control_name ); + if (control_name == "HighResSnapshot" && !checked) + { + // High Res Snapshot active, must uncheck RenderUIInSnapshot + gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE ); + } + gSavedSettings.setBOOL( control_name, !checked ); + return true; + } +}; + +// As above, but can be a callback from a LLCheckboxCtrl +void check_toggle_control( LLUICtrl *, void* user_data ) +{ + BOOL checked = gSavedSettings.getBOOL( static_cast<char*>(user_data) ); + gSavedSettings.setBOOL( static_cast<char*>(user_data), !checked ); +} + +BOOL menu_check_control( void* user_data) +{ + return gSavedSettings.getBOOL((char*)user_data); +} + +// +void menu_toggle_variable( void* user_data ) +{ + BOOL checked = *(BOOL*)user_data; + *(BOOL*)user_data = !checked; +} + +BOOL menu_check_variable( void* user_data) +{ + return *(BOOL*)user_data; +} + + +BOOL enable_land_selected( void* ) +{ + return gParcelMgr && !(gParcelMgr->selectionEmpty()); +} + +class LLSomethingSelected : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = !(gSelectMgr->isEmpty()); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLSomethingSelectedNoHUD : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = !(gSelectMgr->isEmpty()) && !(gSelectMgr->getSelectType() == SELECT_TYPE_HUD); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +BOOL enable_more_than_one_selected(void* ) +{ + return (gSelectMgr->getObjectCount() > 1); +} + +class LLEditableSelected : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = (gSelectMgr->getFirstEditableObject() != NULL); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLToolsEnableTakeCopy : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = false; + if (gSelectMgr) + { + new_value = true; +#ifndef HACKED_GODLIKE_VIEWER +# ifdef TOGGLE_HACKED_GODLIKE_VIEWER + if (gInProductionGrid || !gAgent.isGodlike()) +# endif + { + LLViewerObject* obj = gSelectMgr->getFirstRootObject(); + if(obj) + { + for( ; obj; obj = gSelectMgr->getNextRootObject()) + { + if(!(obj->permCopy()) || obj->isAttachment()) + { + new_value = false; + } + } + } + } +#endif // HACKED_GODLIKE_VIEWER + } + + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +BOOL enable_selection_you_own_all(void*) +{ + LLViewerObject *obj; + for (obj = gSelectMgr->getFirstRootObject(); obj; obj = gSelectMgr->getNextRootObject()) + { + if (!obj->permYouOwner()) + { + return FALSE; + } + } + + return TRUE; +} + +BOOL enable_selection_you_own_one(void*) +{ + LLViewerObject *obj; + for (obj = gSelectMgr->getFirstRootObject(); obj; obj = gSelectMgr->getNextRootObject()) + { + if (obj->permYouOwner()) + { + return TRUE; + } + } + + return FALSE; +} + +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_inventory(void*) +{ + if(gSelectMgr) + { + // find the last root + LLSelectNode* last_node = NULL; + for(LLSelectNode* node = gSelectMgr->getFirstRootNode(); + node != NULL; + node = gSelectMgr->getNextRootNode()) + { + last_node = node; + } + +#ifdef HACKED_GODLIKE_VIEWER + return TRUE; +#else +# ifdef TOGGLE_HACKED_GODLIKE_VIEWER + if (!gInProductionGrid && gAgent.isGodlike()) + { + return TRUE; + } +# endif + // check all pre-req's for save into inventory. + if(last_node && last_node->mValid && !last_node->mItemID.isNull() + && (last_node->mPermissions->getOwner() == gAgent.getID()) + && (gInventory.getItem(last_node->mItemID) != NULL)) + { + LLViewerObject* obj = last_node->getObject(); + if( obj && !obj->isAttachment() ) + { + return TRUE; + } + } +#endif + } + return FALSE; +} + +class LLToolsEnableSaveToInventory : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = enable_save_into_inventory(NULL); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +BOOL enable_save_into_task_inventory(void*) +{ + if(gSelectMgr) + { + LLSelectNode* node = gSelectMgr->getFirstRootNode(); + if(node && (node->mValid) && (!node->mFromTaskID.isNull())) + { + // *FIX: 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(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = enable_save_into_task_inventory(NULL); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +BOOL enable_not_thirdperson(void*) +{ + return !gAgent.cameraThirdPerson(); +} + +class LLFileEnableUpload : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gStatusBar && gGlobalEconomy && (gStatusBar->getBalance() >= gGlobalEconomy->getPriceUpload()); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +BOOL enable_export_selected(void *) +{ + if (gSelectMgr->isEmpty()) + { + return FALSE; + } + if (!gExporterRequestID.isNull()) + { + return FALSE; + } + if (!LLUploadDialog::modalUploadIsFinished()) + { + return FALSE; + } + return TRUE; +} + +class LLViewEnableMouselook : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, 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 != gAgent.getCameraMode() && !gSavedSettings.getBOOL("FreezeTime")); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLToolsEnableToolNotPie : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = ( gToolMgr->getCurrentTool(MASK_NONE) != gToolPie ); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLWorldEnableCreateLandmark : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gAgent.isGodlike() || + (gAgent.getRegion() && gAgent.getRegion()->getAllowLandmark()); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLWorldEnableSetHomeLocation : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = gAgent.isGodlike() || + (gAgent.getRegion() && gAgent.getRegion()->getAllowSetHome()); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +BOOL enable_region_owner(void*) +{ + if(gAgent.getRegion() && gAgent.getRegion()->getOwner() == gAgent.getID()) + return TRUE; + return enable_god_customer_service(NULL); +} + +BOOL enable_god_full(void*) +{ + return gAgent.getGodLevel() >= GOD_FULL; +} + +BOOL enable_god_liaison(void*) +{ + return gAgent.getGodLevel() >= GOD_LIAISON; +} + +BOOL enable_god_customer_service(void*) +{ + return gAgent.getGodLevel() >= GOD_CUSTOMER_SERVICE; +} + +BOOL enable_god_basic(void*) +{ + return gAgent.getGodLevel() > GOD_NOT; +} + +void toggle_vbo(void *) +{ + gPipeline.mUseVBO = !gPipeline.mUseVBO; + + if (!gPipeline.usingAGP()) + { + return; + } + + gPipeline.setUseAGP(FALSE); + gPipeline.setUseAGP(TRUE); + + gSavedSettings.setBOOL("RenderUseVBO", gPipeline.mUseVBO); +} + +BOOL check_vbo(void *) +{ + return gPipeline.mUseVBO; +} + +#if 0 // 1.9.2 +void toggle_vertex_shaders(void *) +{ + BOOL use_shaders = gPipeline.getUseVertexShaders(); + gPipeline.setUseVertexShaders(use_shaders); +} + +BOOL check_vertex_shaders(void *) +{ + return gPipeline.getUseVertexShaders(); +} +#endif + +void toggle_glow(void *) +{ + gRenderLightGlows = !gRenderLightGlows; + + gSavedSettings.setBOOL("RenderLightGlows", gRenderLightGlows); +} + +BOOL check_glow(void *) +{ + return gRenderLightGlows; +} + + +void toggle_show_xui_names(void *) +{ + BOOL showXUINames = gSavedSettings.getBOOL("ShowXUINames"); + + showXUINames = !showXUINames; + gSavedSettings.setBOOL("ShowXUINames", showXUINames); +} + +BOOL check_show_xui_names(void *) +{ + return gSavedSettings.getBOOL("ShowXUINames"); +} + + + +void toggle_cull_small(void *) +{ +// gPipeline.mCullBySize = !gPipeline.mCullBySize; +// +// gSavedSettings.setBOOL("RenderCullBySize", gPipeline.mCullBySize); +} + +class LLToolsSelectOnlyMyObjects : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + BOOL cur_val = gSavedSettings.getBOOL("SelectOwnedOnly"); + + gSavedSettings.setBOOL("SelectOwnedOnly", ! cur_val ); + + return true; + } +}; + +class LLToolsSelectOnlyMovableObjects : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + BOOL cur_val = gSavedSettings.getBOOL("SelectMovableOnly"); + + gSavedSettings.setBOOL("SelectMovableOnly", ! cur_val ); + + return true; + } +}; + +class LLToolsSelectBySurrounding : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLSelectMgr::sRectSelectInclusive = !LLSelectMgr::sRectSelectInclusive; + + gSavedSettings.setBOOL("RectangleSelectInclusive", LLSelectMgr::sRectSelectInclusive); + return true; + } +}; + +class LLToolsShowHiddenSelection : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, 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(LLPointer<LLEvent> event, const LLSD& userdata) + { + // TomY TODO merge these + LLSelectMgr::sRenderLightRadius = !LLSelectMgr::sRenderLightRadius; + + gSavedSettings.setBOOL("RenderLightRadius", LLSelectMgr::sRenderLightRadius); + return true; + } +}; + +void reload_personal_settings_overrides(void *) +{ + llinfos << "Loading overrides from " << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,"overrides.xml") << llendl; + + gSavedSettings.loadFromFile(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,"overrides.xml")); +} + +void force_breakpoint(void *) +{ +#if LL_WINDOWS // Forcing a breakpoint + DebugBreak(); +#endif +} + +void reload_vertex_shader(void *) +{ + //THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought - DaveP +} + +void flush_animations(void *) +{ + if (gAgent.getAvatarObject()) + { + gAgent.getAvatarObject()->resetAnimations(); + } +} + +void slow_mo_animations(void*) +{ + static BOOL slow_mo = FALSE; + if (slow_mo) + { + gAgent.getAvatarObject()->setAnimTimeFactor(1.f); + slow_mo = FALSE; + } + else + { + gAgent.getAvatarObject()->setAnimTimeFactor(0.2f); + slow_mo = TRUE; + } +} + +void handle_dump_avatar_local_textures(void*) +{ + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if( avatar ) + { + avatar->dumpLocalTextures(); + } +} + +void handle_debug_avatar_textures(void*) +{ + LLFloaterAvatarTextures::show(gLastHitObjectID); +} + +void handle_grab_texture(void* data) +{ + LLVOAvatar::ETextureIndex index = (LLVOAvatar::ETextureIndex) ((U32) data); + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if ( avatar ) + { + const LLUUID& asset_id = avatar->grabLocalTexture(index); + llinfos << "Adding baked texture " << asset_id << " to inventory." << llendl; + LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE; + LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE; + LLUUID folder_id(gInventory.findCategoryUUIDForType(asset_type)); + if(folder_id.notNull()) + { + LLString name = "Baked "; + switch (index) + { + case LLVOAvatar::TEX_EYES_BAKED: + name.append("Iris"); + break; + case LLVOAvatar::TEX_HEAD_BAKED: + name.append("Head"); + break; + case LLVOAvatar::TEX_UPPER_BAKED: + name.append("Upper Body"); + break; + case LLVOAvatar::TEX_LOWER_BAKED: + name.append("Lower Body"); + break; + case LLVOAvatar::TEX_SKIRT_BAKED: + name.append("Skirt"); + break; + default: + name.append("Unknown"); + break; + } + name.append(" 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); + S32 creation_date_now = time_corrected(); + LLPointer<LLViewerInventoryItem> item + = new LLViewerInventoryItem(item_id, + folder_id, + perm, + asset_id, + asset_type, + inv_type, + name, + "", + LLSaleInfo::DEFAULT, + LLInventoryItem::II_FLAGS_NONE, + creation_date_now); + + item->updateServer(TRUE); + gInventory.updateItem(item); + gInventory.notifyObservers(); + + LLInventoryView* view = LLInventoryView::getActiveInventory(); + + // Show the preview panel for textures to let + // user know that the image is now in inventory. + if(view) + { + LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus(); + LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback(); + + view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO); + view->getPanel()->openSelected(); + //LLInventoryView::dumpSelectionInformation((void*)view); + // restore keyboard focus + gFocusMgr.setKeyboardFocus(focus_ctrl, callback); + } + } + else + { + llwarns << "Can't find a folder to put it in" << llendl; + } + } +} + +BOOL enable_grab_texture(void* data) +{ + LLVOAvatar::ETextureIndex index = (LLVOAvatar::ETextureIndex) ((U32) data); + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if ( avatar ) + { + return avatar->canGrabLocalTexture(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(void *) +{ + char message[2048]; + message[0] = '\0'; + + sprintf(message, "Testing viewer disconnect"); + + do_disconnect(message); +} + + +class LLToolsUseSelectionForGrid : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + gSelectMgr->clearGridObjects(); + + for (LLViewerObject* objectp = gSelectMgr->getFirstRootObject(); + objectp; + objectp = gSelectMgr->getNextRootObject()) + { + gSelectMgr->addGridObject(objectp); + } + gSelectMgr->setGridMode(GRID_MODE_REF_OBJECT); + if (gFloaterTools) + { + gFloaterTools->mComboGridMode->setCurrentByIndex((S32)GRID_MODE_REF_OBJECT); + } + return true; + } +}; + +void handle_test_load_url(void*) +{ + LLWeb::loadURL(""); + LLWeb::loadURL("hacker://www.google.com/"); + LLWeb::loadURL("http"); + LLWeb::loadURL("http://www.google.com/"); +} + +// +// LLViewerMenuHolderGL +// + +BOOL LLViewerMenuHolderGL::hideMenus() +{ + BOOL handled = LLMenuHolderGL::hideMenus(); + if (handled) + { + gSelectMgr->deselectTransient(); + if (!gFloaterTools->getVisible() && !LLFloaterLand::floaterVisible()) + { + gParcelMgr->deselectLand(); + } + } + return handled; +} + +void handle_save_to_xml(void*) +{ + LLFloater* frontmost = gFloaterView->getFrontmost(); + if (!frontmost) + { + gViewerWindow->alertXml("NoFrontmostFloater"); + return; + } + + LLString default_name = "floater_"; + default_name += frontmost->getTitle(); + default_name += ".xml"; + + LLString::toLower(default_name); + LLString::replaceChar(default_name, ' ', '_'); + LLString::replaceChar(default_name, '/', '_'); + LLString::replaceChar(default_name, ':', '_'); + LLString::replaceChar(default_name, '"', '_'); + + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getSaveFile(LLFilePicker::FFSAVE_XML, default_name.c_str())) + { + LLString filename = picker.getFirstFile(); + gUICtrlFactory->saveToXML(frontmost, filename); + } +} + +void handle_load_from_xml(void*) +{ + LLFilePicker& picker = LLFilePicker::instance(); + if (picker.getOpenFile(LLFilePicker::FFLOAD_XML)) + { + LLString filename = picker.getFirstFile(); + LLFloater* floater = new LLFloater("sample_floater"); + gUICtrlFactory->buildFloater(floater, filename); + } +} + +void handle_rebake_textures(void*) +{ + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if (!avatar) return; + + // Slam pending upload count to "unstick" things + bool slam_for_debug = true; + avatar->forceBakeAllTextures(slam_for_debug); +} + +void toggle_visibility(void* user_data) +{ + LLView* viewp = (LLView*)user_data; + viewp->setVisible(!viewp->getVisible()); +} + +BOOL get_visibility(void* user_data) +{ + LLView* viewp = (LLView*)user_data; + return viewp->getVisible(); +} + +// TomY TODO: Get rid of these? +class LLViewShowHoverTips : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLHoverView::sShowHoverTips = !LLHoverView::sShowHoverTips; + return true; + } +}; + +class LLViewCheckShowHoverTips : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = LLHoverView::sShowHoverTips; + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +// TomY TODO: Get rid of these? +class LLViewHighlightTransparent : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha; + return true; + } +}; + +class LLViewCheckHighlightTransparent : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = LLDrawPoolAlpha::sShowDebugAlpha; + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLViewToggleBeacon : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString beacon = userdata.asString(); + if (beacon == "scripts") + { + LLPipeline::toggleRenderScriptedBeacons(NULL); + } + else if (beacon == "physical") + { + LLPipeline::toggleRenderPhysicalBeacons(NULL); + } + else if (beacon == "sounds") + { + LLPipeline::toggleRenderSoundBeacons(NULL); + } + else if (beacon == "particles") + { + LLPipeline::toggleRenderParticleBeacons(NULL); + } + return true; + } +}; + +class LLViewCheckBeaconEnabled : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString beacon = userdata["data"].asString(); + bool new_value = false; + if (beacon == "scripts") + { + new_value = LLPipeline::getRenderScriptedBeacons(NULL); + } + else if (beacon == "physical") + { + new_value = LLPipeline::getRenderPhysicalBeacons(NULL); + } + else if (beacon == "sounds") + { + new_value = LLPipeline::getRenderSoundBeacons(NULL); + } + else if (beacon == "particles") + { + new_value = LLPipeline::getRenderParticleBeacons(NULL); + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLViewToggleRenderType : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString type = userdata.asString(); + if (type == "particles") + { + LLPipeline::toggleRenderType((void *)(S32)LLPipeline::RENDER_TYPE_PARTICLES); + } + return true; + } +}; + +class LLViewCheckRenderType : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString type = userdata["data"].asString(); + bool new_value = false; + if (type == "particles") + { + new_value = LLPipeline::toggleRenderTypeControlNegated((void *)(S32)LLPipeline::RENDER_TYPE_PARTICLES); + } + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +// TomY TODO: Get rid of these? +class LLViewShowHUDAttachments : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLDrawPoolHUD::sShowHUDAttachments = !LLDrawPoolHUD::sShowHUDAttachments; + return true; + } +}; + +class LLViewCheckHUDAttachments : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = LLDrawPoolHUD::sShowHUDAttachments; + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + +class LLEditEnableTakeOff : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString control_name = userdata["control"].asString(); + LLString clothing = userdata["data"].asString(); + bool new_value = false; + if (clothing == "shirt") + { + new_value = LLAgent::selfHasWearable((void *)WT_SHIRT); + } + if (clothing == "pants") + { + new_value = LLAgent::selfHasWearable((void *)WT_PANTS); + } + if (clothing == "shoes") + { + new_value = LLAgent::selfHasWearable((void *)WT_SHOES); + } + if (clothing == "socks") + { + new_value = LLAgent::selfHasWearable((void *)WT_SOCKS); + } + if (clothing == "jacket") + { + new_value = LLAgent::selfHasWearable((void *)WT_JACKET); + } + if (clothing == "gloves") + { + new_value = LLAgent::selfHasWearable((void *)WT_GLOVES); + } + if (clothing == "undershirt") + { + new_value = LLAgent::selfHasWearable((void *)WT_UNDERSHIRT); + } + if (clothing == "underpants") + { + new_value = LLAgent::selfHasWearable((void *)WT_UNDERPANTS); + } + if (clothing == "skirt") + { + new_value = LLAgent::selfHasWearable((void *)WT_SKIRT); + } + gMenuHolder->findControl(control_name)->setValue(new_value); + return true; + } +}; + +class LLEditTakeOff : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString clothing = userdata.asString(); + if (clothing == "shirt") + { + LLAgent::userRemoveWearable((void*)WT_SHIRT); + } + else if (clothing == "pants") + { + LLAgent::userRemoveWearable((void*)WT_PANTS); + } + else if (clothing == "shoes") + { + LLAgent::userRemoveWearable((void*)WT_SHOES); + } + else if (clothing == "socks") + { + LLAgent::userRemoveWearable((void*)WT_SOCKS); + } + else if (clothing == "jacket") + { + LLAgent::userRemoveWearable((void*)WT_JACKET); + } + else if (clothing == "gloves") + { + LLAgent::userRemoveWearable((void*)WT_GLOVES); + } + else if (clothing == "undershirt") + { + LLAgent::userRemoveWearable((void*)WT_UNDERSHIRT); + } + else if (clothing == "underpants") + { + LLAgent::userRemoveWearable((void*)WT_UNDERPANTS); + } + else if (clothing == "skirt") + { + LLAgent::userRemoveWearable((void*)WT_SKIRT); + } + else if (clothing == "all") + { + LLAgent::userRemoveAllClothes(NULL); + } + return true; + } +}; + +class LLWorldChat : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + handle_chat(NULL); + return true; + } +}; + +class LLWorldStartGesture : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + handle_slash_key(NULL); + return true; + } +}; + +class LLToolsSelectTool : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + LLString tool_name = userdata.asString(); + if (tool_name == "focus") + { + gCurrentToolset->selectToolByIndex(1); + } + else if (tool_name == "move") + { + gCurrentToolset->selectToolByIndex(2); + } + else if (tool_name == "edit") + { + gCurrentToolset->selectToolByIndex(3); + } + else if (tool_name == "create") + { + gCurrentToolset->selectToolByIndex(4); + } + else if (tool_name == "land") + { + gCurrentToolset->selectToolByIndex(5); + } + return true; + } +}; + +void initialize_menu_actions() +{ + // File menu + (new LLFileUploadImage())->registerListener(gMenuHolder, "File.UploadImage"); + (new LLFileUploadSound())->registerListener(gMenuHolder, "File.UploadSound"); + (new LLFileUploadAnim())->registerListener(gMenuHolder, "File.UploadAnim"); + (new LLFileUploadBulk())->registerListener(gMenuHolder, "File.UploadBulk"); + (new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow"); + (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture"); + (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot"); + (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk"); + (new LLFileSaveMovie())->registerListener(gMenuHolder, "File.SaveMovie"); + (new LLFileSetWindowSize())->registerListener(gMenuHolder, "File.SetWindowSize"); + (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit"); + + (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload"); + (new LLFileEnableSaveAs())->registerListener(gMenuHolder, "File.EnableSaveAs"); + + // Edit menu + (new LLEditUndo())->registerListener(gMenuHolder, "Edit.Undo"); + (new LLEditRedo())->registerListener(gMenuHolder, "Edit.Redo"); + (new LLEditCut())->registerListener(gMenuHolder, "Edit.Cut"); + (new LLEditCopy())->registerListener(gMenuHolder, "Edit.Copy"); + (new LLEditPaste())->registerListener(gMenuHolder, "Edit.Paste"); + (new LLEditDelete())->registerListener(gMenuHolder, "Edit.Delete"); + (new LLEditSearch())->registerListener(gMenuHolder, "Edit.Search"); + (new LLEditSelectAll())->registerListener(gMenuHolder, "Edit.SelectAll"); + (new LLEditDeselect())->registerListener(gMenuHolder, "Edit.Deselect"); + (new LLEditDuplicate())->registerListener(gMenuHolder, "Edit.Duplicate"); + (new LLEditTakeOff())->registerListener(gMenuHolder, "Edit.TakeOff"); + + (new LLEditEnableUndo())->registerListener(gMenuHolder, "Edit.EnableUndo"); + (new LLEditEnableRedo())->registerListener(gMenuHolder, "Edit.EnableRedo"); + (new LLEditEnableCut())->registerListener(gMenuHolder, "Edit.EnableCut"); + (new LLEditEnableCopy())->registerListener(gMenuHolder, "Edit.EnableCopy"); + (new LLEditEnablePaste())->registerListener(gMenuHolder, "Edit.EnablePaste"); + (new LLEditEnableDelete())->registerListener(gMenuHolder, "Edit.EnableDelete"); + (new LLEditEnableSelectAll())->registerListener(gMenuHolder, "Edit.EnableSelectAll"); + (new LLEditEnableDeselect())->registerListener(gMenuHolder, "Edit.EnableDeselect"); + (new LLEditEnableDuplicate())->registerListener(gMenuHolder, "Edit.EnableDuplicate"); + (new LLEditEnableTakeOff())->registerListener(gMenuHolder, "Edit.EnableTakeOff"); + (new LLEditEnableCustomizeAvatar())->registerListener(gMenuHolder, "Edit.EnableCustomizeAvatar"); + + // View menu + (new LLViewMouselook())->registerListener(gMenuHolder, "View.Mouselook"); + (new LLViewBuildMode())->registerListener(gMenuHolder, "View.BuildMode"); + (new LLViewResetView())->registerListener(gMenuHolder, "View.ResetView"); + (new LLViewLookAtLastChatter())->registerListener(gMenuHolder, "View.LookAtLastChatter"); + (new LLViewShowHoverTips())->registerListener(gMenuHolder, "View.ShowHoverTips"); + (new LLViewHighlightTransparent())->registerListener(gMenuHolder, "View.HighlightTransparent"); + (new LLViewToggleBeacon())->registerListener(gMenuHolder, "View.ToggleBeacon"); + (new LLViewToggleRenderType())->registerListener(gMenuHolder, "View.ToggleRenderType"); + (new LLViewShowHUDAttachments())->registerListener(gMenuHolder, "View.ShowHUDAttachments"); + (new LLViewZoomOut())->registerListener(gMenuHolder, "View.ZoomOut"); + (new LLViewZoomIn())->registerListener(gMenuHolder, "View.ZoomIn"); + (new LLViewZoomDefault())->registerListener(gMenuHolder, "View.ZoomDefault"); + (new LLViewFullscreen())->registerListener(gMenuHolder, "View.Fullscreen"); + (new LLViewDefaultUISize())->registerListener(gMenuHolder, "View.DefaultUISize"); + + (new LLViewEnableMouselook())->registerListener(gMenuHolder, "View.EnableMouselook"); + (new LLViewEnableLastChatter())->registerListener(gMenuHolder, "View.EnableLastChatter"); + + (new LLViewCheckBuildMode())->registerListener(gMenuHolder, "View.CheckBuildMode"); + (new LLViewCheckShowHoverTips())->registerListener(gMenuHolder, "View.CheckShowHoverTips"); + (new LLViewCheckHighlightTransparent())->registerListener(gMenuHolder, "View.CheckHighlightTransparent"); + (new LLViewCheckBeaconEnabled())->registerListener(gMenuHolder, "View.CheckBeaconEnabled"); + (new LLViewCheckRenderType())->registerListener(gMenuHolder, "View.CheckRenderType"); + (new LLViewCheckHUDAttachments())->registerListener(gMenuHolder, "View.CheckHUDAttachments"); + + // World menu + (new LLWorldChat())->registerListener(gMenuHolder, "World.Chat"); + (new LLWorldStartGesture())->registerListener(gMenuHolder, "World.StartGesture"); + (new LLWorldAlwaysRun())->registerListener(gMenuHolder, "World.AlwaysRun"); + (new LLWorldFly())->registerListener(gMenuHolder, "World.Fly"); + (new LLWorldCreateLandmark())->registerListener(gMenuHolder, "World.CreateLandmark"); + (new LLWorldSetHomeLocation())->registerListener(gMenuHolder, "World.SetHomeLocation"); + (new LLWorldTeleportHome())->registerListener(gMenuHolder, "World.TeleportHome"); + (new LLWorldSetAway())->registerListener(gMenuHolder, "World.SetAway"); + (new LLWorldSetBusy())->registerListener(gMenuHolder, "World.SetBusy"); + + (new LLWorldEnableCreateLandmark())->registerListener(gMenuHolder, "World.EnableCreateLandmark"); + (new LLWorldEnableSetHomeLocation())->registerListener(gMenuHolder, "World.EnableSetHomeLocation"); + (new LLWorldEnableBuyLand())->registerListener(gMenuHolder, "World.EnableBuyLand"); + + (new LLWorldCheckAlwaysRun())->registerListener(gMenuHolder, "World.CheckAlwaysRun"); + + (new LLWorldForceSun())->registerListener(gMenuHolder, "World.ForceSun"); + + // Tools menu + (new LLToolsSelectTool())->registerListener(gMenuHolder, "Tools.SelectTool"); + (new LLToolsSelectOnlyMyObjects())->registerListener(gMenuHolder, "Tools.SelectOnlyMyObjects"); + (new LLToolsSelectOnlyMovableObjects())->registerListener(gMenuHolder, "Tools.SelectOnlyMovableObjects"); + (new LLToolsSelectBySurrounding())->registerListener(gMenuHolder, "Tools.SelectBySurrounding"); + (new LLToolsShowHiddenSelection())->registerListener(gMenuHolder, "Tools.ShowHiddenSelection"); + (new LLToolsShowSelectionLightRadius())->registerListener(gMenuHolder, "Tools.ShowSelectionLightRadius"); + (new LLToolsSnapObjectXY())->registerListener(gMenuHolder, "Tools.SnapObjectXY"); + (new LLToolsUseSelectionForGrid())->registerListener(gMenuHolder, "Tools.UseSelectionForGrid"); + (new LLToolsLink())->registerListener(gMenuHolder, "Tools.Link"); + (new LLToolsUnlink())->registerListener(gMenuHolder, "Tools.Unlink"); + (new LLToolsStopAllAnimations())->registerListener(gMenuHolder, "Tools.StopAllAnimations"); + (new LLToolsLookAtSelection())->registerListener(gMenuHolder, "Tools.LookAtSelection"); + (new LLToolsBuyOrTake())->registerListener(gMenuHolder, "Tools.BuyOrTake"); + (new LLToolsTakeCopy())->registerListener(gMenuHolder, "Tools.TakeCopy"); + (new LLToolsSaveToInventory())->registerListener(gMenuHolder, "Tools.SaveToInventory"); + (new LLToolsSaveToObjectInventory())->registerListener(gMenuHolder, "Tools.SaveToObjectInventory"); + (new LLToolsSelectedScriptAction())->registerListener(gMenuHolder, "Tools.SelectedScriptAction"); + + (new LLToolsEnableToolNotPie())->registerListener(gMenuHolder, "Tools.EnableToolNotPie"); + (new LLToolsEnableLink())->registerListener(gMenuHolder, "Tools.EnableLink"); + (new LLToolsEnableUnlink())->registerListener(gMenuHolder, "Tools.EnableUnlink"); + (new LLToolsEnableBuyOrTake())->registerListener(gMenuHolder, "Tools.EnableBuyOrTake"); + (new LLToolsEnableTakeCopy())->registerListener(gMenuHolder, "Tools.EnableTakeCopy"); + (new LLToolsEnableSaveToInventory())->registerListener(gMenuHolder, "Tools.SaveToInventory"); + (new LLToolsEnableSaveToObjectInventory())->registerListener(gMenuHolder, "Tools.SaveToObjectInventory"); + + /*(new LLToolsVisibleBuyObject())->registerListener(gMenuHolder, "Tools.VisibleBuyObject"); + (new LLToolsVisibleTakeObject())->registerListener(gMenuHolder, "Tools.VisibleTakeObject");*/ + + // Help menu + (new LLHelpLiveHelp())->registerListener(gMenuHolder, "Help.LiveHelp"); + (new LLHelpMOTD())->registerListener(gMenuHolder, "Help.MOTD"); + + // Self pie menu + (new LLSelfStandUp())->registerListener(gMenuHolder, "Self.StandUp"); + (new LLSelfRemoveAllAttachments())->registerListener(gMenuHolder, "Self.RemoveAllAttachments"); + + (new LLSelfEnableStandUp())->registerListener(gMenuHolder, "Self.EnableStandUp"); + (new LLSelfEnableRemoveAllAttachments())->registerListener(gMenuHolder, "Self.EnableRemoveAllAttachments"); + + // Avatar pie menu + (new LLObjectMute())->registerListener(gMenuHolder, "Avatar.Mute"); + (new LLAvatarRate())->registerListener(gMenuHolder, "Avatar.Rate"); + (new LLAvatarAddFriend())->registerListener(gMenuHolder, "Avatar.AddFriend"); + (new LLAvatarFreeze())->registerListener(gMenuHolder, "Avatar.Freeze"); + (new LLAvatarDebug())->registerListener(gMenuHolder, "Avatar.Debug"); + (new LLAvatarVisibleDebug())->registerListener(gMenuHolder, "Avatar.VisibleDebug"); + (new LLAvatarEnableDebug())->registerListener(gMenuHolder, "Avatar.EnableDebug"); + (new LLAvatarGiveCard())->registerListener(gMenuHolder, "Avatar.GiveCard"); + (new LLAvatarEject())->registerListener(gMenuHolder, "Avatar.Eject"); + (new LLAvatarSendIM())->registerListener(gMenuHolder, "Avatar.SendIM"); + + (new LLObjectEnableMute())->registerListener(gMenuHolder, "Avatar.EnableMute"); + (new LLAvatarEnableAddFriend())->registerListener(gMenuHolder, "Avatar.EnableAddFriend"); + (new LLAvatarEnableFreezeEject())->registerListener(gMenuHolder, "Avatar.EnableFreezeEject"); + + // Object pie menu + (new LLObjectOpen())->registerListener(gMenuHolder, "Object.Open"); + (new LLObjectBuild())->registerListener(gMenuHolder, "Object.Build"); + (new LLObjectTouch())->registerListener(gMenuHolder, "Object.Touch"); + (new LLObjectSitOrStand())->registerListener(gMenuHolder, "Object.SitOrStand"); + (new LLObjectDelete())->registerListener(gMenuHolder, "Object.Delete"); + (new LLObjectAttachToAvatar())->registerListener(gMenuHolder, "Object.AttachToAvatar"); + (new LLObjectReturn())->registerListener(gMenuHolder, "Object.Return"); + (new LLObjectRateOwner())->registerListener(gMenuHolder, "Object.RateOwner"); + (new LLObjectReportAbuse())->registerListener(gMenuHolder, "Object.ReportAbuse"); + (new LLObjectRateCreator())->registerListener(gMenuHolder, "Object.RateCreator"); + (new LLObjectMute())->registerListener(gMenuHolder, "Object.Mute"); + (new LLObjectBuy())->registerListener(gMenuHolder, "Object.Buy"); + (new LLObjectEdit())->registerListener(gMenuHolder, "Object.Edit"); + + (new LLObjectEnableOpen())->registerListener(gMenuHolder, "Object.EnableOpen"); + (new LLObjectEnableTouch())->registerListener(gMenuHolder, "Object.EnableTouch"); + (new LLObjectEnableSitOrStand())->registerListener(gMenuHolder, "Object.EnableSitOrStand"); + (new LLObjectEnableDelete())->registerListener(gMenuHolder, "Object.EnableDelete"); + (new LLObjectEnableWear())->registerListener(gMenuHolder, "Object.EnableWear"); + (new LLObjectEnableReturn())->registerListener(gMenuHolder, "Object.EnableReturn"); + (new LLObjectEnableRateOwner())->registerListener(gMenuHolder, "Object.EnableRateOwner"); + (new LLObjectEnableReportAbuse())->registerListener(gMenuHolder, "Object.EnableReportAbuse"); + (new LLObjectEnableRateCreator())->registerListener(gMenuHolder, "Object.EnableRateCreator"); + (new LLObjectEnableMute())->registerListener(gMenuHolder, "Object.EnableMute"); + (new LLObjectEnableBuy())->registerListener(gMenuHolder, "Object.EnableBuy"); + + /*(new LLObjectVisibleTouch())->registerListener(gMenuHolder, "Object.VisibleTouch"); + (new LLObjectVisibleCustomTouch())->registerListener(gMenuHolder, "Object.VisibleCustomTouch"); + (new LLObjectVisibleStandUp())->registerListener(gMenuHolder, "Object.VisibleStandUp"); + (new LLObjectVisibleSitHere())->registerListener(gMenuHolder, "Object.VisibleSitHere"); + (new LLObjectVisibleCustomSit())->registerListener(gMenuHolder, "Object.VisibleCustomSit");*/ + + // Attachment pie menu + (new LLAttachmentDrop())->registerListener(gMenuHolder, "Attachment.Drop"); + (new LLAttachmentDetach())->registerListener(gMenuHolder, "Attachment.Detach"); + + (new LLAttachmentEnableDrop())->registerListener(gMenuHolder, "Attachment.EnableDrop"); + (new LLAttachmentEnableDetach())->registerListener(gMenuHolder, "Attachment.EnableDetach"); + + // Land pie menu + (new LLLandBuild())->registerListener(gMenuHolder, "Land.Build"); + (new LLLandSit())->registerListener(gMenuHolder, "Land.Sit"); + (new LLLandBuyPass())->registerListener(gMenuHolder, "Land.BuyPass"); + (new LLLandEdit())->registerListener(gMenuHolder, "Land.Edit"); + + (new LLLandEnableBuyPass())->registerListener(gMenuHolder, "Land.EnableBuyPass"); + + // Generic actions + (new LLShowFloater())->registerListener(gMenuHolder, "ShowFloater"); + (new LLPromptShowURL())->registerListener(gMenuHolder, "PromptShowURL"); + (new LLPromptShowFile())->registerListener(gMenuHolder, "PromptShowFile"); + (new LLShowAgentProfile())->registerListener(gMenuHolder, "ShowAgentProfile"); + (new LLShowAgentGroups())->registerListener(gMenuHolder, "ShowAgentGroups"); + (new LLToggleControl())->registerListener(gMenuHolder, "ToggleControl"); + + (new LLGoToObject())->registerListener(gMenuHolder, "GoToObject"); + (new LLPayObject())->registerListener(gMenuHolder, "PayObject"); + + (new LLEnablePayObject())->registerListener(gMenuHolder, "EnablePayObject"); + (new LLEnableEdit())->registerListener(gMenuHolder, "EnableEdit"); + + (new LLFloaterVisible())->registerListener(gMenuHolder, "FloaterVisible"); + (new LLSomethingSelected())->registerListener(gMenuHolder, "SomethingSelected"); + (new LLSomethingSelectedNoHUD())->registerListener(gMenuHolder, "SomethingSelectedNoHUD"); + (new LLEditableSelected())->registerListener(gMenuHolder, "EditableSelected"); +} |