llviewermenu.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "llviewermenu.h" 
00035 
00036 // system library includes
00037 #include <iostream>
00038 #include <fstream>
00039 #include <sstream>
00040 
00041 // linden library includes
00042 #include "audioengine.h"
00043 #include "indra_constants.h"
00044 #include "llassetstorage.h"
00045 #include "llchat.h"
00046 #include "llfeaturemanager.h"
00047 #include "llfocusmgr.h"
00048 #include "llfontgl.h"
00049 #include "llinstantmessage.h"
00050 #include "llpermissionsflags.h"
00051 #include "llrect.h"
00052 #include "llsecondlifeurls.h"
00053 #include "lltransactiontypes.h"
00054 #include "llui.h"
00055 #include "llview.h"
00056 #include "llxfermanager.h"
00057 #include "message.h"
00058 #include "raytrace.h"
00059 #include "llsdserialize.h"
00060 #include "lltimer.h"
00061 #include "llvfile.h"
00062 #include "llvolumemgr.h"
00063 #include "llwindow.h"   // for shell_open()
00064 
00065 // newview includes
00066 #include "llagent.h"
00067 
00068 #include "llagentpilot.h"
00069 #include "llbox.h"
00070 #include "llcallingcard.h"
00071 #include "llcameraview.h"
00072 #include "llclipboard.h"
00073 #include "llcompilequeue.h"
00074 #include "llconsole.h"
00075 #include "llviewercontrol.h"
00076 #include "lldebugview.h"
00077 #include "lldir.h"
00078 #include "lldrawable.h"
00079 #include "lldrawpoolalpha.h"
00080 #include "lldrawpooltree.h"
00081 #include "llface.h"
00082 #include "llfirstuse.h"
00083 #include "llfloater.h"
00084 #include "llfloaterabout.h"
00085 #include "llfloaterbuycurrency.h"
00086 #include "llfloateractivespeakers.h"
00087 #include "llfloateranimpreview.h"
00088 #include "llfloateravatarinfo.h"
00089 #include "llfloateravatartextures.h"
00090 #include "llfloaterbuildoptions.h"
00091 #include "llfloaterbump.h"
00092 #include "llfloaterbuy.h"
00093 #include "llfloaterbuycontents.h"
00094 #include "llfloaterbuycurrency.h"
00095 #include "llfloaterbuyland.h"
00096 #include "llfloaterchat.h"
00097 #include "llfloatercustomize.h"
00098 #include "llfloaterdirectory.h"
00099 #include "llfloatereditui.h"
00100 #include "llfloatereventlog.h"
00101 #include "llfloaterchatterbox.h"
00102 #include "llfloaterfriends.h"
00103 #include "llfloatergesture.h"
00104 #include "llfloatergodtools.h"
00105 #include "llfloatergroupinfo.h"
00106 #include "llfloatergroupinvite.h"
00107 #include "llfloatergroups.h"
00108 #include "llfloaterhtml.h"
00109 #include "llfloaterhtmlhelp.h"
00110 #include "llfloaterinspect.h"
00111 #include "llfloaterlagmeter.h"
00112 #include "llfloaterland.h"
00113 #include "llfloaterlandholdings.h"
00114 #include "llfloatermap.h"
00115 #include "llfloatermute.h"
00116 #include "llfloateropenobject.h"
00117 #include "llfloaterpermissionsmgr.h"
00118 #include "llfloaterpreference.h"
00119 #include "llfloaterproject.h"
00120 #include "llfloaterregioninfo.h"
00121 #include "llfloaterreporter.h"
00122 #include "llfloaterscriptdebug.h"
00123 #include "llfloatertest.h"
00124 #include "llfloatertools.h"
00125 #include "llfloatertrustnetrate.h"
00126 #include "llfloaterworldmap.h"
00127 #include "llframestats.h"
00128 #include "llframestatview.h"
00129 #include "llfasttimerview.h"
00130 #include "llmemoryview.h"
00131 #include "llgivemoney.h"
00132 #include "llgroupmgr.h"
00133 #include "llhoverview.h"
00134 #include "llhudeffecttrail.h"
00135 #include "llhudmanager.h"
00136 #include "llimage.h"
00137 #include "llimagebmp.h"
00138 #include "llimagej2c.h"
00139 #include "llimagetga.h"
00140 #include "llinventorymodel.h"
00141 #include "llinventoryview.h"
00142 #include "llkeyboard.h"
00143 #include "llpanellogin.h"
00144 #include "llfloaterlandmark.h"
00145 #include "llmenucommands.h"
00146 #include "llmenugl.h"
00147 #include "llmorphview.h"
00148 #include "llmoveview.h"
00149 #include "llmutelist.h"
00150 #include "llnotify.h"
00151 #include "llpanelobject.h"
00152 #include "llparcel.h"
00153 #include "llprimitive.h"
00154 #include "llresmgr.h"
00155 #include "llselectmgr.h"
00156 #include "llsky.h"
00157 #include "llstatusbar.h"
00158 #include "llstatview.h"
00159 #include "llstring.h"
00160 #include "llsurfacepatch.h"
00161 #include "llimview.h"
00162 #include "lltextureview.h"
00163 #include "lltool.h"
00164 #include "lltoolbar.h"
00165 #include "lltoolcomp.h"
00166 #include "lltoolfocus.h"
00167 #include "lltoolgrab.h"
00168 #include "lltoolmgr.h"
00169 #include "lltoolpie.h"
00170 #include "lltoolplacer.h"
00171 #include "lltoolselectland.h"
00172 #include "llvieweruictrlfactory.h"
00173 #include "lluploaddialog.h"
00174 #include "lluserauth.h"
00175 #include "lluuid.h"
00176 #include "llvelocitybar.h"
00177 #include "llviewercamera.h"
00178 #include "llviewergenericmessage.h"
00179 #include "llviewergesture.h"
00180 #include "llviewerinventory.h"
00181 #include "llviewermenufile.h"   // init_menu_file()
00182 #include "llviewermessage.h"
00183 #include "llviewernetwork.h"
00184 #include "llviewerobjectlist.h"
00185 #include "llviewerparcelmgr.h"
00186 #include "llviewerparceloverlay.h"
00187 #include "llviewerregion.h"
00188 #include "llviewerstats.h"
00189 #include "llviewerwindow.h"
00190 #include "llvoavatar.h"
00191 #include "llvolume.h"
00192 #include "llweb.h"
00193 #include "llworld.h"
00194 #include "llworldmap.h"
00195 #include "object_flags.h"
00196 #include "pipeline.h"
00197 #include "viewer.h"
00198 #include "roles_constants.h"
00199 #include "llfloateravatarlist.h"
00200 #include "llviewerjoystick.h"
00201 
00202 #include "lltexlayer.h"
00203 
00204 void init_landmark_menu(LLMenuGL* menu);
00205 void clear_landmark_menu(LLMenuGL* menu);
00206 
00207 void init_client_menu(LLMenuGL* menu);
00208 void init_server_menu(LLMenuGL* menu);
00209 
00210 void init_debug_world_menu(LLMenuGL* menu);
00211 void init_debug_rendering_menu(LLMenuGL* menu);
00212 void init_debug_ui_menu(LLMenuGL* menu);
00213 void init_debug_xui_menu(LLMenuGL* menu);
00214 void init_debug_avatar_menu(LLMenuGL* menu);
00215 void init_debug_baked_texture_menu(LLMenuGL* menu);
00216 
00217 BOOL enable_land_build(void*);
00218 BOOL enable_object_build(void*);
00219 
00220 LLVOAvatar* find_avatar_from_object( LLViewerObject* object );
00221 LLVOAvatar* find_avatar_from_object( const LLUUID& object_id );
00222 
00223 void handle_test_load_url(void*);
00224 
00225 extern void disconnect_viewer(void *);
00226 
00227 //
00228 // Evil hackish imported globals
00229 //
00230 extern BOOL     gRenderLightGlows;
00231 extern BOOL gRenderAvatar;
00232 extern BOOL     gHideSelectedObjects;
00233 extern BOOL gShowOverlayTitle;
00234 extern BOOL gRandomizeFramerate;
00235 extern BOOL gPeriodicSlowFrame;
00236 extern BOOL gOcclusionCull;
00237 extern BOOL gAllowSelectAvatar;
00238 
00239 //
00240 // Globals
00241 //
00242 
00243 LLMenuBarGL             *gMenuBarView = NULL;
00244 LLViewerMenuHolderGL    *gMenuHolder = NULL;
00245 LLMenuGL                *gPopupMenuView = NULL;
00246 
00247 // Pie menus
00248 LLPieMenu       *gPieSelf       = NULL;
00249 LLPieMenu       *gPieAvatar = NULL;
00250 LLPieMenu       *gPieObject = NULL;
00251 LLPieMenu       *gPieAttachment = NULL;
00252 LLPieMenu       *gPieLand       = NULL;
00253 
00254 // local constants
00255 const LLString LANDMARK_MENU_NAME("Landmarks");
00256 const LLString CLIENT_MENU_NAME("Client");
00257 const LLString SERVER_MENU_NAME("Server");
00258 
00259 const LLString SAVE_INTO_INVENTORY("Save Object Back to My Inventory");
00260 const LLString SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents");
00261 
00262 #if LL_WINDOWS
00263 static const char* SOUND_EXTENSIONS = ".wav";
00264 static const char* IMAGE_EXTENSIONS = ".tga .bmp .jpg .jpeg .png";
00265 static const char* ANIM_EXTENSIONS =  ".bvh";
00266 #ifdef _CORY_TESTING
00267 static const char* GEOMETRY_EXTENSIONS = ".slg";
00268 #endif
00269 static const char* XML_EXTENSIONS = ".xml";
00270 static const char* SLOBJECT_EXTENSIONS = ".slobject";
00271 #endif
00272 static const char* ALL_FILE_EXTENSIONS = "*.*";
00273 
00274 LLMenuGL* gAttachSubMenu = NULL;
00275 LLMenuGL* gDetachSubMenu = NULL;
00276 LLMenuGL* gTakeOffClothes = NULL;
00277 LLPieMenu* gPieRate = NULL;
00278 LLPieMenu* gAttachScreenPieMenu = NULL;
00279 LLPieMenu* gAttachPieMenu = NULL;
00280 LLPieMenu* gAttachBodyPartPieMenus[8];
00281 LLPieMenu* gDetachPieMenu = NULL;
00282 LLPieMenu* gDetachScreenPieMenu = NULL;
00283 LLPieMenu* gDetachBodyPartPieMenus[8];
00284 
00285 LLMenuGL* gLandmarkMenu = NULL;
00286 LLMenuItemCallGL* gAFKMenu = NULL;
00287 LLMenuItemCallGL* gBusyMenu = NULL;
00288 
00289 typedef LLMemberListener<LLView> view_listener_t;
00290 
00291 //
00292 // Local prototypes
00293 //
00294 void handle_leave_group(void *);
00295 
00296 // File Menu
00297 const char* upload_pick(void* data);
00298 void handle_upload(void* data);
00299 //void handle_upload_object(void* data);
00300 void handle_compress_image(void*);
00301 BOOL enable_save_as(void *);
00302 
00303 // Edit menu
00304 void handle_dump_group_info(void *);
00305 void handle_dump_capabilities_info(void *);
00306 void handle_dump_focus(void*);
00307 
00308 void handle_region_dump_settings(void*);
00309 void handle_region_dump_temp_asset_data(void*);
00310 void handle_region_clear_temp_asset_data(void*);
00311 
00312 // Object pie menu
00313 BOOL sitting_on_selection();
00314 
00315 void near_sit_object();
00316 void label_sit_or_stand(LLString& label, void*);
00317 // buy and take alias into the same UI positions, so these
00318 // declarations handle this mess.
00319 BOOL is_selection_buy_not_take();
00320 S32 selection_price();
00321 BOOL enable_take();
00322 void handle_take();
00323 void confirm_take(S32 option, void* data);
00324 BOOL enable_buy(void*); 
00325 void handle_buy(void *);
00326 void handle_buy_object(LLSaleInfo sale_info);
00327 void handle_buy_contents(LLSaleInfo sale_info);
00328 void label_touch(LLString& label, void*);
00329 
00330 // Land pie menu
00331 void near_sit_down_point(BOOL success, void *);
00332 
00333 // Avatar pie menu
00334 void handle_follow(void *userdata);
00335 void handle_talk_to(void *userdata);
00336 
00337 // Debug menu
00338 void show_permissions_control(void*);
00339 void load_url_local_file(const char* file_name);
00340 void toggle_build_options(void* user_data);
00341 #if 0 // Unused
00342 void handle_audio_status_1(void*);
00343 void handle_audio_status_2(void*);
00344 void handle_audio_status_3(void*);
00345 void handle_audio_status_4(void*);
00346 #endif
00347 void manage_landmarks(void*);
00348 void create_new_landmark(void*);
00349 void landmark_menu_action(void*);
00350 void reload_ui(void*);
00351 void handle_agent_stop_moving(void*);
00352 void print_packets_lost(void*);
00353 void drop_packet(void*);
00354 void velocity_interpolate( void* data );
00355 void update_fov(S32 increments);
00356 void toggle_wind_audio(void);
00357 void toggle_water_audio(void);
00358 void handle_rebake_textures(void*);
00359 BOOL check_admin_override(void*);
00360 void handle_admin_override_toggle(void*);
00361 #ifdef TOGGLE_HACKED_GODLIKE_VIEWER
00362 void handle_toggle_hacked_godmode(void*);
00363 BOOL check_toggle_hacked_godmode(void*);
00364 #endif
00365 
00366 void toggle_glow(void *);
00367 BOOL check_glow(void *);
00368 
00369 void toggle_vertex_shaders(void *);
00370 BOOL check_vertex_shaders(void *);
00371 
00372 void toggle_cull_small(void *);
00373 
00374 void toggle_show_xui_names(void *);
00375 BOOL check_show_xui_names(void *);
00376 
00377 // Debug UI
00378 void handle_web_search_demo(void*);
00379 void handle_slurl_test(void*);
00380 void handle_save_to_xml(void*);
00381 void handle_load_from_xml(void*);
00382 
00383 void handle_god_mode(void*);
00384 
00385 // God menu
00386 void handle_leave_god_mode(void*);
00387 
00388 BOOL is_inventory_visible( void* user_data );
00389 void handle_reset_view();
00390 
00391 void disabled_duplicate(void*);
00392 void handle_duplicate_in_place(void*);
00393 void handle_repeat_duplicate(void*);
00394 
00395 void handle_export(void*);
00396 void handle_deed_object_to_group(void*);
00397 BOOL enable_deed_object_to_group(void*);
00398 void handle_object_owner_self(void*);
00399 void handle_object_owner_permissive(void*);
00400 void handle_object_lock(void*);
00401 void handle_object_asset_ids(void*);
00402 void force_take_copy(void*);
00403 #ifdef _CORY_TESTING
00404 void force_export_copy(void*);
00405 void force_import_geometry(void*);
00406 #endif
00407 
00408 void handle_force_parcel_owner_to_me(void*);
00409 void handle_force_parcel_to_content(void*);
00410 void handle_claim_public_land(void*);
00411 
00412 void handle_god_request_havok(void *);
00413 void handle_god_request_avatar_geometry(void *);        // Hack for easy testing of new avatar geometry
00414 void reload_personal_settings_overrides(void *);
00415 void force_breakpoint(void *);
00416 void reload_vertex_shader(void *);
00417 void slow_mo_animations(void *);
00418 void handle_disconnect_viewer(void *);
00419 
00420 void handle_stopall(void*);
00421 //void handle_hinge(void*);
00422 //void handle_ptop(void*);
00423 //void handle_lptop(void*);
00424 //void handle_wheel(void*);
00425 //void handle_dehinge(void*);
00426 BOOL enable_dehinge(void*);
00427 void handle_force_delete(void*);
00428 void print_object_info(void*);
00429 void show_debug_menus();
00430 void toggle_debug_menus(void*);
00431 void toggle_map( void* user_data );
00432 void export_info_callback(LLAssetInfo *info, void **user_data, S32 result);
00433 void export_data_callback(LLVFS *vfs, const LLUUID& uuid, LLAssetType::EType type, void **user_data, S32 result);
00434 void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExtStat ext_status);
00435 BOOL menu_check_build_tool( void* user_data );
00436 void handle_reload_settings(void*);
00437 void focus_here(void*);
00438 void dump_select_mgr(void*);
00439 void dump_volume_mgr(void*);
00440 void dump_inventory(void*);
00441 void edit_ui(void*);
00442 void toggle_visibility(void*);
00443 BOOL get_visibility(void*);
00444 
00445 // Avatar Pie menu
00446 void request_friendship(const LLUUID& agent_id);
00447 
00448 // Tools menu
00449 void handle_force_unlock(void*);
00450 void handle_selected_texture_info(void*);
00451 void handle_dump_image_list(void*);
00452 
00453 void handle_fullscreen_debug(void*);
00454 void handle_crash(void*);
00455 void handle_dump_followcam(void*);
00456 void handle_toggle_flycam(void*);
00457 BOOL check_flycam(void*);
00458 void handle_viewer_enable_message_log(void*);
00459 void handle_viewer_disable_message_log(void*);
00460 void handle_send_postcard(void*);
00461 void handle_gestures_old(void*);
00462 void handle_focus(void *);
00463 BOOL enable_buy_land(void*);
00464 void handle_move(void*);
00465 void handle_show_inventory(void*);
00466 void handle_activate(void*);
00467 BOOL enable_activate(void*);
00468 
00469 // Help menu
00470 void handle_buy_currency(void*);
00471 
00472 void handle_test_male(void *);
00473 void handle_test_female(void *);
00474 void handle_toggle_pg(void*);
00475 void handle_dump_attachments(void *);
00476 void handle_show_overlay_title(void*);
00477 void handle_dump_avatar_local_textures(void*);
00478 void handle_debug_avatar_textures(void*);
00479 void handle_grab_texture(void*);
00480 BOOL enable_grab_texture(void*);
00481 void handle_dump_region_object_cache(void*);
00482 
00483 BOOL menu_ui_enabled(void *user_data);
00484 void check_toggle_control( LLUICtrl *, void* user_data );
00485 BOOL menu_check_control( void* user_data);
00486 void menu_toggle_variable( void* user_data );
00487 BOOL menu_check_variable( void* user_data);
00488 BOOL enable_land_selected( void* );
00489 BOOL enable_more_than_one_selected(void* );
00490 BOOL enable_selection_you_own_all(void*);
00491 BOOL enable_selection_you_own_one(void*);
00492 BOOL enable_save_into_inventory(void*);
00493 BOOL enable_save_into_task_inventory(void*);
00494 BOOL enable_not_thirdperson(void*);
00495 BOOL enable_export_selected(void *);
00496 BOOL enable_have_card(void*);
00497 BOOL enable_detach(void*);
00498 BOOL enable_region_owner(void*);
00499 
00500 class LLLandmarkObserver : public LLInventoryObserver
00501 {
00502 public:
00503         LLLandmarkObserver();
00504         virtual ~LLLandmarkObserver();
00505 
00506         virtual void changed(U32 mask)
00507         {
00508                 // JAMESDEBUG disabled for now - slows down client or causes crashes
00509                 // in inventory code.
00510                 //
00511                 // Also, this may not be faster than just rebuilding the menu each time.
00512                 // I believe gInventory.getObject() is not fast.
00513                 //
00514                 //const std::set<LLUUID>& changed_ids = gInventory.getChangedIDs();
00515                 //std::set<LLUUID>::const_iterator id_it;
00516                 //BOOL need_to_rebuild_menu = FALSE;
00517                 //for(id_it = changed_ids.begin(); id_it != changed_ids.end(); ++id_it)
00518                 //{
00519                 //      LLInventoryObject* objectp = gInventory.getObject(*id_it);
00520                 //      if (objectp && (objectp->getType() == LLAssetType::AT_LANDMARK || objectp->getType() == LLAssetType::AT_CATEGORY))
00521                 //      {
00522                 //              need_to_rebuild_menu = TRUE;
00523                 //      }
00524                 //}
00525                 //if (need_to_rebuild_menu)
00526                 //{
00527                 //      init_landmark_menu(gLandmarkMenu);
00528                 //}
00529         }
00530 };
00531 
00532 // For debugging only, I think the inventory observer doesn't get 
00533 // called if the inventory is loaded from cache.
00534 void build_landmark_menu(void*)
00535 {
00536         init_landmark_menu(gLandmarkMenu);
00537 }
00538 
00539 LLLandmarkObserver::LLLandmarkObserver()
00540 {
00541         gInventory.addObserver(this);
00542 }
00543 
00544 LLLandmarkObserver::~LLLandmarkObserver()
00545 {
00546         gInventory.removeObserver(this);
00547 }
00548 
00549 class LLMenuParcelObserver : public LLParcelObserver
00550 {
00551 public:
00552         LLMenuParcelObserver();
00553         ~LLMenuParcelObserver();
00554         virtual void changed();
00555 };
00556 
00557 static LLMenuParcelObserver* gMenuParcelObserver = NULL;
00558 static LLLandmarkObserver* gLandmarkObserver = NULL;
00559 
00560 LLMenuParcelObserver::LLMenuParcelObserver()
00561 {
00562         gParcelMgr->addObserver(this);
00563 }
00564 
00565 LLMenuParcelObserver::~LLMenuParcelObserver()
00566 {
00567         gParcelMgr->removeObserver(this);
00568 }
00569 
00570 void LLMenuParcelObserver::changed()
00571 {
00572         gMenuHolder->childSetEnabled("Land Buy Pass", LLPanelLandGeneral::enableBuyPass(NULL));
00573         
00574         BOOL buyable = enable_buy_land(NULL);
00575         gMenuHolder->childSetEnabled("Land Buy", buyable);
00576         gMenuHolder->childSetEnabled("Buy Land...", buyable);
00577 }
00578 
00579 
00580 //-----------------------------------------------------------------------------
00581 // Menu Construction
00582 //-----------------------------------------------------------------------------
00583 
00584 // code required to calculate anything about the menus
00585 void pre_init_menus()
00586 {
00587         // static information
00588         LLColor4 color;
00589         color = gColors.getColor( "MenuDefaultBgColor" );
00590         LLMenuGL::setDefaultBackgroundColor( color );
00591         color = gColors.getColor( "MenuItemEnabledColor" );
00592         LLMenuItemGL::setEnabledColor( color );
00593         color = gColors.getColor( "MenuItemDisabledColor" );
00594         LLMenuItemGL::setDisabledColor( color );
00595         color = gColors.getColor( "MenuItemHighlightBgColor" );
00596         LLMenuItemGL::setHighlightBGColor( color );
00597         color = gColors.getColor( "MenuItemHighlightFgColor" );
00598         LLMenuItemGL::setHighlightFGColor( color );
00599 }
00600 
00601 void initialize_menus();
00602 
00603 //-----------------------------------------------------------------------------
00604 // Initialize main menus
00605 //
00606 // HOW TO NAME MENUS:
00607 //
00608 // First Letter Of Each Word Is Capitalized, Even At Or And
00609 //
00610 // Items that lead to dialog boxes end in "..."
00611 //
00612 // Break up groups of more than 6 items with separators
00613 //-----------------------------------------------------------------------------
00614 void init_menus()
00615 {
00616         S32 top = gViewerWindow->getRootView()->getRect().getHeight();
00617         S32 width = gViewerWindow->getRootView()->getRect().getWidth();
00618 
00619         //
00620         // Main menu bar
00621         //
00622         gMenuHolder = new LLViewerMenuHolderGL();
00623         gMenuHolder->setRect(LLRect(0, top, width, 0));
00624         gMenuHolder->setFollowsAll();
00625 
00626         LLMenuGL::sMenuContainer = gMenuHolder;
00627 
00628         // Initialize actions
00629         initialize_menus();
00630 
00636         
00637         gPopupMenuView = new LLMenuGL( "Popup" );
00638         gPopupMenuView->setVisible( FALSE );
00639         gMenuHolder->addChild( gPopupMenuView );
00640 
00644         gPieSelf = gUICtrlFactory->buildPieMenu("menu_pie_self.xml", gMenuHolder);
00645 
00646         // TomY TODO: what shall we do about these?
00647         gDetachScreenPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Detach HUD", true);
00648         gDetachPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Detach", true);
00649 
00650         if (gAgent.isTeen())
00651         {
00652                 gMenuHolder->getChildByName("Self Underpants", TRUE)->setVisible(FALSE);
00653                 gMenuHolder->getChildByName("Self Undershirt", TRUE)->setVisible(FALSE);
00654         }
00655 
00656         gPieAvatar = gUICtrlFactory->buildPieMenu("menu_pie_avatar.xml", gMenuHolder);
00657 
00658         gPieObject = gUICtrlFactory->buildPieMenu("menu_pie_object.xml", gMenuHolder);
00659 
00660         gAttachScreenPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Attach HUD", true);
00661         gAttachPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Attach", true);
00662         gPieRate = (LLPieMenu*)gMenuHolder->getChildByName("Rate Menu", true);
00663 
00664         gPieAttachment = gUICtrlFactory->buildPieMenu("menu_pie_attachment.xml", gMenuHolder);
00665 
00666         gPieLand = gUICtrlFactory->buildPieMenu("menu_pie_land.xml", gMenuHolder);
00667 
00671         LLColor4 color;
00672 
00673         LLColor4 pie_color = gColors.getColor("PieMenuBgColor");
00674         gPieSelf->setBackgroundColor( pie_color );
00675         gPieAvatar->setBackgroundColor( pie_color );
00676         gPieObject->setBackgroundColor( pie_color );
00677         gPieAttachment->setBackgroundColor( pie_color );
00678         gPieLand->setBackgroundColor( pie_color );
00679 
00680         color = gColors.getColor( "MenuPopupBgColor" );
00681         gPopupMenuView->setBackgroundColor( color );
00682 
00683         // If we are not in production, use a different color to make it apparent.
00684         if (gInProductionGrid)
00685         {
00686                 color = gColors.getColor( "MenuBarBgColor" );
00687         }
00688         else
00689         {
00690                 color = gColors.getColor( "MenuNonProductionBgColor" );
00691         }
00692         gMenuBarView = (LLMenuBarGL*)gUICtrlFactory->buildMenu("menu_viewer.xml", gMenuHolder);
00693         gMenuBarView->setRect(LLRect(0, top, 0, top - MENU_BAR_HEIGHT));
00694         gMenuBarView->setBackgroundColor( color );
00695 
00696         gMenuHolder->addChild(gMenuBarView);
00697         
00698         // menu holder appears on top of menu bar so you can see the menu title
00699         // flash when an item is triggered (the flash occurs in the holder)
00700         gViewerWindow->getRootView()->addChild(gMenuHolder);
00701 
00702         // *TODO:Get the cost info from the server
00703         const LLString upload_cost("10");
00704         gMenuHolder->childSetLabelArg("Upload Image", "[COST]", upload_cost);
00705         gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", upload_cost);
00706         gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", upload_cost);
00707         gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
00708 
00709         gAFKMenu = (LLMenuItemCallGL*)gMenuBarView->getChildByName("Set Away", TRUE);
00710         gBusyMenu = (LLMenuItemCallGL*)gMenuBarView->getChildByName("Set Busy", TRUE);
00711         gAttachSubMenu = gMenuBarView->getChildMenuByName("Attach Object", TRUE);
00712         gDetachSubMenu = gMenuBarView->getChildMenuByName("Detach Object", TRUE);
00713 
00714         if (gAgent.isTeen())
00715         {
00716                 gMenuBarView->getChildByName("Menu Underpants", TRUE)->setVisible(FALSE);
00717                 gMenuBarView->getChildByName("Menu Undershirt", TRUE)->setVisible(FALSE);
00718         }
00719 
00720         // TomY TODO convert these two
00721         LLMenuGL*menu;
00722 
00723         // JAMESDEBUG - Maybe we don't want a global landmark menu
00724         /*
00725         menu = new LLMenuGL(LANDMARK_MENU_NAME);
00726         // Defer init_landmark_menu() until inventory observer reports that we actually
00727         // have inventory.  Otherwise findCategoryByUUID() will create an empty
00728         // Landmarks folder in inventory. JC
00729         gMenuBarView->appendMenu( menu );
00730         menu->updateParent(LLMenuGL::sMenuContainer);
00731         gLandmarkMenu = menu;
00732         */
00733 
00734         menu = new LLMenuGL(CLIENT_MENU_NAME);
00735         init_client_menu(menu);
00736         gMenuBarView->appendMenu( menu );
00737         menu->updateParent(LLMenuGL::sMenuContainer);
00738 
00739         menu = new LLMenuGL(SERVER_MENU_NAME);
00740         init_server_menu(menu);
00741         gMenuBarView->appendMenu( menu );
00742         menu->updateParent(LLMenuGL::sMenuContainer);
00743 
00744         gMenuBarView->createJumpKeys();
00745 
00746         // Let land based option enable when parcel changes
00747         gMenuParcelObserver = new LLMenuParcelObserver();
00748 
00749         // Let landmarks menu update when landmarks are added/removed
00750         gLandmarkObserver = new LLLandmarkObserver();
00751 
00752         //
00753         // Debug menu visiblity
00754         //
00755         show_debug_menus();
00756 }
00757 
00758 void init_landmark_menu(LLMenuGL* menu)
00759 {
00760         if (!menu) return;
00761 
00762         // clear existing menu, as we might be rebuilding as result of inventory update
00763         clear_landmark_menu(menu);
00764 
00765         menu->append(new LLMenuItemCallGL("Organize Landmarks", 
00766                         &manage_landmarks, NULL));
00767         menu->append(new LLMenuItemCallGL("New Landmark...", 
00768                         &create_new_landmark, NULL));
00769         menu->appendSeparator();
00770         
00771         // now collect all landmarks in inventory and build menu...
00772         LLInventoryModel::cat_array_t* cats;
00773         LLInventoryModel::item_array_t* items;
00774         gInventory.getDirectDescendentsOf(gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK), cats, items);
00775         if(items)
00776         {
00777                 S32 count = items->count();
00778                 for(S32 i = 0; i < count; ++i)
00779                 {
00780                         LLInventoryItem* item = items->get(i);
00781                         LLString landmark_name = item->getName();
00782                         LLUUID* landmark_id_ptr = new LLUUID( item->getUUID() );
00783                         LLMenuItemCallGL* menu_item =
00784                                 new LLMenuItemCallGL(landmark_name, landmark_menu_action, 
00785                                         NULL, NULL,     landmark_id_ptr);
00786                         menu->append(menu_item);
00787                 }
00788         }
00789 }
00790 
00791 void clear_landmark_menu(LLMenuGL* menu)
00792 {
00793         if (!menu) return;
00794 
00795         // We store the UUIDs of the landmark inventory items in the userdata
00796         // field of the menus.  Therefore when we clean up the menu we need to
00797         // delete that data.
00798         const LLView::child_list_t* child_list = menu->getChildList();
00799         LLView::child_list_const_iter_t it = child_list->begin();
00800         for ( ; it != child_list->end(); ++it)
00801         {
00802                 LLView* view = *it;
00803                 if (view->getWidgetType() == WIDGET_TYPE_MENU_ITEM_CALL)
00804                 {
00805                         LLMenuItemCallGL* menu_item = (LLMenuItemCallGL*)view;
00806                         if (menu_item->getMenuCallback() == landmark_menu_action)
00807                         {
00808                                 void* user_data = menu_item->getUserData();
00809                                 delete (LLUUID*)user_data;
00810                         }
00811                 }
00812         }
00813 
00814         menu->empty();
00815 }
00816 
00817 void init_client_menu(LLMenuGL* menu)
00818 {
00819         LLMenuGL* sub_menu = NULL;
00820 
00821         //menu->append(new LLMenuItemCallGL("Permissions Control", &show_permissions_control));
00822 
00823 // this is now in the view menu so we don't need it here!
00824         {
00825                 LLMenuGL* sub = new LLMenuGL("Consoles");
00826                 menu->appendMenu(sub);
00827                 sub->append(new LLMenuItemCheckGL("Frame Console", 
00828                                                                                 &toggle_visibility,
00829                                                                                 NULL,
00830                                                                                 &get_visibility,
00831                                                                                 (void*)gDebugView->mFrameStatView,
00832                                                                                 '2', MASK_CONTROL|MASK_SHIFT ) );
00833                 sub->append(new LLMenuItemCheckGL("Texture Console", 
00834                                                                                 &toggle_visibility,
00835                                                                                 NULL,
00836                                                                                 &get_visibility,
00837                                                                                 (void*)gTextureView,
00838                                                                                 '3', MASK_CONTROL|MASK_SHIFT ) );
00839                 LLView* debugview = gDebugView->mDebugConsolep;
00840                 sub->append(new LLMenuItemCheckGL("Debug Console", 
00841                                                                                 &toggle_visibility,
00842                                                                                 NULL,
00843                                                                                 &get_visibility,
00844                                                                                 debugview,
00845                                                                                 '4', MASK_CONTROL|MASK_SHIFT ) );
00846 #if 0 // Unused
00847         {
00848                 LLMenuGL* sub = new LLMenuGL("Audio");
00849                 menu->appendMenu(sub);
00850 
00851                 sub->append(new LLMenuItemCallGL("Global Pos", 
00852                                         &handle_audio_status_1, NULL, NULL ,'5', MASK_CONTROL|MASK_SHIFT) );
00853                 sub->append(new LLMenuItemCallGL("Cone", 
00854                                         &handle_audio_status_2, NULL, NULL ,'6', MASK_CONTROL|MASK_SHIFT) );
00855                 sub->append(new LLMenuItemCallGL("Local Pos", 
00856                                         &handle_audio_status_3, NULL, NULL ,'7', MASK_CONTROL|MASK_SHIFT) );
00857                 sub->append(new LLMenuItemCallGL("Duration", 
00858                                         &handle_audio_status_4, NULL, NULL ,'8', MASK_CONTROL|MASK_SHIFT) );
00859                 sub->createJumpKeys();
00860         }
00861 #endif
00862                 sub->append(new LLMenuItemCheckGL("Fast Timers", 
00863                                                                                 &toggle_visibility,
00864                                                                                 NULL,
00865                                                                                 &get_visibility,
00866                                                                                 (void*)gDebugView->mFastTimerView,
00867                                                                                 '9', MASK_CONTROL|MASK_SHIFT ) );
00868                 sub->append(new LLMenuItemCheckGL("Memory", 
00869                                                                                 &toggle_visibility,
00870                                                                                 NULL,
00871                                                                                 &get_visibility,
00872                                                                                 (void*)gDebugView->mMemoryView,
00873                                                                                 '0', MASK_CONTROL|MASK_SHIFT ) );
00874                 sub->appendSeparator();
00875                 sub->append(new LLMenuItemCallGL("Region Info to Debug Console", 
00876                         &handle_region_dump_settings, NULL));
00877                 sub->append(new LLMenuItemCallGL("Group Info to Debug Console",
00878                         &handle_dump_group_info, NULL, NULL));
00879                 sub->append(new LLMenuItemCallGL("Capabilities Info to Debug Console",
00880                         &handle_dump_capabilities_info, NULL, NULL));
00881                 sub->createJumpKeys();
00882         }
00883         
00884         // neither of these works particularly well at the moment
00885         /*menu->append(new LLMenuItemCallGL(  "Reload UI XML",  &reload_ui,     
00886                                         NULL, NULL) );*/
00887         /*menu->append(new LLMenuItemCallGL("Reload settings/colors", 
00888                                         &handle_reload_settings, NULL, NULL));*/
00889         menu->append(new LLMenuItemCallGL("Reload personal setting overrides", 
00890                 &reload_personal_settings_overrides, NULL, NULL, KEY_F2, MASK_CONTROL|MASK_SHIFT));
00891 
00892         sub_menu = new LLMenuGL("HUD Info");
00893         {
00894                 sub_menu->append(new LLMenuItemCheckGL("Velocity", 
00895                                                                                                 &toggle_visibility,
00896                                                                                                 NULL,
00897                                                                                                 &get_visibility,
00898                                                                                                 (void*)gVelocityBar));
00899 
00900                 sub_menu->append(new LLMenuItemToggleGL("Camera",       &gDisplayCameraPos ) );
00901                 sub_menu->append(new LLMenuItemToggleGL("Wind",         &gDisplayWindInfo) );
00902                 sub_menu->append(new LLMenuItemToggleGL("FOV",          &gDisplayFOV ) );
00903                 sub_menu->createJumpKeys();
00904         }
00905         menu->appendMenu(sub_menu);
00906 
00907         menu->appendSeparator();
00908 
00909         menu->append(new LLMenuItemCheckGL( "High-res Snapshot",
00910                                                                                 &menu_toggle_control,
00911                                                                                 NULL,
00912                                                                                 &menu_check_control,
00913                                                                                 (void*)"HighResSnapshot"));
00914         
00915         menu->append(new LLMenuItemCheckGL( "Quiet Snapshots to Disk",
00916                                                                                 &menu_toggle_control,
00917                                                                                 NULL,
00918                                                                                 &menu_check_control,
00919                                                                                 (void*)"QuietSnapshotsToDisk"));
00920 
00921         menu->append(new LLMenuItemCheckGL( "Compress Snapshots to Disk",
00922                                                                                 &menu_toggle_control,
00923                                                                                 NULL,
00924                                                                                 &menu_check_control,
00925                                                                                 (void*)"CompressSnapshotsToDisk"));
00926 
00927         menu->append(new LLMenuItemCheckGL("Show Mouselook Crosshairs",
00928                                                                            &menu_toggle_control,
00929                                                                            NULL,
00930                                                                            &menu_check_control,
00931                                                                            (void*)"ShowCrosshairs"));
00932 
00933         menu->append(new LLMenuItemCheckGL("Debug Permissions",
00934                                                                            &menu_toggle_control,
00935                                                                            NULL,
00936                                                                            &menu_check_control,
00937                                                                            (void*)"DebugPermissions"));
00938         
00939 
00940 
00941 #ifdef TOGGLE_HACKED_GODLIKE_VIEWER
00942         if (!gInProductionGrid)
00943         {
00944                 menu->append(new LLMenuItemCheckGL("Hacked Godmode",
00945                                                                                    &handle_toggle_hacked_godmode,
00946                                                                                    NULL,
00947                                                                                    &check_toggle_hacked_godmode,
00948                                                                                    (void*)"HackedGodmode"));
00949         }
00950 #endif
00951 
00952         menu->append(new LLMenuItemCallGL("Clear Group Cache", 
00953                                                                           LLGroupMgr::debugClearAllGroups));
00954         menu->appendSeparator();
00955 
00956         sub_menu = new LLMenuGL("Rendering");
00957         init_debug_rendering_menu(sub_menu);
00958         menu->appendMenu(sub_menu);
00959 
00960         sub_menu = new LLMenuGL("World");
00961         init_debug_world_menu(sub_menu);
00962         menu->appendMenu(sub_menu);
00963 
00964         sub_menu = new LLMenuGL("UI");
00965         init_debug_ui_menu(sub_menu);
00966         menu->appendMenu(sub_menu);
00967 
00968         sub_menu = new LLMenuGL("XUI");
00969         init_debug_xui_menu(sub_menu);
00970         menu->appendMenu(sub_menu);
00971 
00972         sub_menu = new LLMenuGL("Character");
00973         init_debug_avatar_menu(sub_menu);
00974         menu->appendMenu(sub_menu);
00975 
00976 {
00977                 LLMenuGL* sub = NULL;
00978                 sub = new LLMenuGL("Network");
00979 
00980                 sub->append(new LLMenuItemCallGL("Enable Message Log",  
00981                         &handle_viewer_enable_message_log,  NULL));
00982                 sub->append(new LLMenuItemCallGL("Disable Message Log", 
00983                         &handle_viewer_disable_message_log, NULL));
00984 
00985                 sub->appendSeparator();
00986 
00987                 sub->append(new LLMenuItemCheckGL("Velocity Interpolate Objects", 
00988                                                                                   &velocity_interpolate,
00989                                                                                   NULL, 
00990                                                                                   &menu_check_control,
00991                                                                                   (void*)"VelocityInterpolate"));
00992                 sub->append(new LLMenuItemCheckGL("Ping Interpolate Object Positions", 
00993                                                                                   &menu_toggle_control,
00994                                                                                   NULL, 
00995                                                                                   &menu_check_control,
00996                                                                                   (void*)"PingInterpolate"));
00997 
00998                 sub->appendSeparator();
00999 
01000                 sub->append(new LLMenuItemCallGL("Drop a Packet", 
01001                         &drop_packet, NULL, NULL, 
01002                         'L', MASK_ALT | MASK_CONTROL));
01003 
01004                 menu->appendMenu( sub );
01005                 sub->createJumpKeys();
01006         }
01007         {
01008                 LLMenuGL* sub = NULL;
01009                 sub = new LLMenuGL("Recorder");
01010 
01011                 sub->append(new LLMenuItemCheckGL("Full Session Logging", &menu_toggle_control, NULL, &menu_check_control, (void*)"StatsSessionTrackFrameStats"));
01012 
01013                 sub->append(new LLMenuItemCallGL("Start Logging",       &LLFrameStats::startLogging, NULL));
01014                 sub->append(new LLMenuItemCallGL("Stop Logging",        &LLFrameStats::stopLogging, NULL));
01015                 sub->append(new LLMenuItemCallGL("Log 10 Seconds", &LLFrameStats::timedLogging10, NULL));
01016                 sub->append(new LLMenuItemCallGL("Log 30 Seconds", &LLFrameStats::timedLogging30, NULL));
01017                 sub->append(new LLMenuItemCallGL("Log 60 Seconds", &LLFrameStats::timedLogging60, NULL));
01018                 sub->appendSeparator();
01019                 sub->append(new LLMenuItemCallGL("Start Playback", &LLAgentPilot::startPlayback, NULL));
01020                 sub->append(new LLMenuItemCallGL("Stop Playback",       &LLAgentPilot::stopPlayback, NULL));
01021                 sub->append(new LLMenuItemToggleGL("Loop Playback", &LLAgentPilot::sLoop) );
01022                 sub->append(new LLMenuItemCallGL("Start Record",        &LLAgentPilot::startRecord, NULL));
01023                 sub->append(new LLMenuItemCallGL("Stop Record", &LLAgentPilot::saveRecord, NULL));
01024 
01025                 menu->appendMenu( sub );
01026                 sub->createJumpKeys();
01027         }
01028 
01029         menu->appendSeparator();
01030 
01031         menu->append(new LLMenuItemToggleGL("Show Updates", 
01032                 &gShowObjectUpdates,
01033                 'U', MASK_ALT | MASK_SHIFT | MASK_CONTROL));
01034         
01035         menu->appendSeparator(); 
01036         
01037         menu->append(new LLMenuItemCallGL("Compress Image...", 
01038                 &handle_compress_image, NULL, NULL));
01039 
01040         menu->append(new LLMenuItemCheckGL("Limit Select Distance", 
01041                                                                            &menu_toggle_control,
01042                                                                            NULL, 
01043                                                                            &menu_check_control,
01044                                                                            (void*)"LimitSelectDistance"));
01045 
01046         menu->append(new LLMenuItemCheckGL("Disable Camera Constraints", 
01047                                                                            &menu_toggle_control,
01048                                                                            NULL, 
01049                                                                            &menu_check_control,
01050                                                                            (void*)"DisableCameraConstraints"));
01051 
01052         menu->append(new LLMenuItemCheckGL("Joystick Flycam", 
01053                 &handle_toggle_flycam,NULL,&check_flycam,NULL));
01054                 
01055         menu->append(new LLMenuItemCheckGL("Mouse Smoothing",
01056                                                                                 &menu_toggle_control,
01057                                                                                 NULL,
01058                                                                                 &menu_check_control,
01059                                                                                 (void*) "MouseSmooth"));
01060         menu->appendSeparator();
01061 
01062         menu->append(new LLMenuItemCheckGL( "Console Window", 
01063                                                                                 &menu_toggle_control,
01064                                                                                 NULL, 
01065                                                                                 &menu_check_control,
01066                                                                                 (void*)"ShowConsoleWindow"));
01067 
01068 #ifndef LL_RELEASE_FOR_DOWNLOAD
01069         {
01070                 LLMenuGL* sub = NULL;
01071                 sub = new LLMenuGL("Debugging");
01072                 sub->append(new LLMenuItemCallGL("Force Breakpoint", &force_breakpoint, NULL, NULL, 'B', MASK_CONTROL | MASK_ALT));
01073                 sub->append(new LLMenuItemCallGL("LLError And Crash", &handle_crash));
01074                 sub->createJumpKeys();
01075                 menu->appendMenu(sub);
01076         }
01077 #endif  
01078 
01079         // TomY Temporary menu item so we can test this floater
01080         menu->append(new LLMenuItemCheckGL("Clothing...", 
01081                                                                                                 &handle_clothing,
01082                                                                                                 NULL,
01083                                                                                                 NULL,
01084                                                                                                 NULL));
01085 
01086         menu->append(new LLMenuItemCallGL("Debug Settings", LLFloaterSettingsDebug::show, NULL, NULL));
01087         menu->append(new LLMenuItemCheckGL("View Admin Options", &handle_admin_override_toggle, NULL, &check_admin_override, NULL, 'V', MASK_CONTROL | MASK_ALT));
01088         menu->createJumpKeys();
01089 }
01090 
01091 void init_debug_world_menu(LLMenuGL* menu)
01092 {
01093         menu->append(new LLMenuItemCheckGL("Mouse Moves Sun", 
01094                                                                            &menu_toggle_control,
01095                                                                            NULL, 
01096                                                                            &menu_check_control,
01097                                                                            (void*)"MouseSun", 
01098                                                                            'M', MASK_CONTROL|MASK_ALT));
01099         menu->append(new LLMenuItemCheckGL("Sim Sun Override", 
01100                                                                            &menu_toggle_control,
01101                                                                            NULL, 
01102                                                                            &menu_check_control,
01103                                                                            (void*)"SkyOverrideSimSunPosition"));
01104         menu->append(new LLMenuItemCallGL("Dump Scripted Camera",
01105                 &handle_dump_followcam, NULL, NULL));
01106         menu->append(new LLMenuItemCheckGL("Fixed Weather", 
01107                                                                            &menu_toggle_control,
01108                                                                            NULL, 
01109                                                                            &menu_check_control,
01110                                                                            (void*)"FixedWeather"));
01111         menu->append(new LLMenuItemCallGL("Dump Region Object Cache",
01112                 &handle_dump_region_object_cache, NULL, NULL));
01113         menu->createJumpKeys();
01114 }
01115 
01116 
01117 void handle_export_menus_to_xml(void*)
01118 {
01119         LLFilePicker& picker = LLFilePicker::instance();
01120         if(!picker.getSaveFile(LLFilePicker::FFSAVE_XML))
01121         {
01122                 llwarns << "No file" << llendl;
01123                 return;
01124         }
01125         const char* filename = picker.getFirstFile();
01126 
01127         llofstream out(filename);
01128         LLXMLNodePtr node = gMenuBarView->getXML();
01129         node->writeToOstream(out);
01130         out.close();
01131 }
01132 
01133 extern BOOL gDebugClicks;
01134 extern BOOL gDebugWindowProc;
01135 extern BOOL gDebugTextEditorTips;
01136 extern BOOL gDebugSelectMgr;
01137 extern BOOL gVectorizePerfTest;
01138 
01139 void init_debug_ui_menu(LLMenuGL* menu)
01140 {
01141         menu->append(new LLMenuItemCallGL("SLURL Test", &handle_slurl_test));
01142         menu->append(new LLMenuItemCallGL("Editable UI", &edit_ui));
01143         menu->append(new LLMenuItemToggleGL("Async Keystrokes", &gHandleKeysAsync));
01144         menu->append(new LLMenuItemCallGL( "Dump SelectMgr", &dump_select_mgr));
01145         menu->append(new LLMenuItemCallGL( "Dump Inventory", &dump_inventory));
01146         menu->append(new LLMenuItemCallGL( "Dump Focus Holder", &handle_dump_focus, NULL, NULL, 'F', MASK_ALT | MASK_CONTROL));
01147         menu->append(new LLMenuItemCallGL( "Dump VolumeMgr",    &dump_volume_mgr, NULL, NULL));
01148         menu->append(new LLMenuItemCallGL( "Print Selected Object Info",        &print_object_info, NULL, NULL, 'P', MASK_CONTROL|MASK_SHIFT ));
01149         menu->append(new LLMenuItemCallGL( "Print Agent Info",                  &print_agent_nvpairs, NULL, NULL, 'P', MASK_SHIFT ));
01150         menu->append(new LLMenuItemCallGL( "Texture Memory Stats",  &output_statistics, NULL, NULL, 'M', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
01151         menu->append(new LLMenuItemCheckGL("Double-Click Auto-Pilot", 
01152                 menu_toggle_control, NULL, menu_check_control, 
01153                 (void*)"DoubleClickAutoPilot"));
01154         menu->appendSeparator();
01155 //      menu->append(new LLMenuItemCallGL( "Print Packets Lost",                        &print_packets_lost, NULL, NULL, 'L', MASK_SHIFT ));
01156         menu->append(new LLMenuItemToggleGL("Debug SelectMgr", &gDebugSelectMgr));
01157         menu->append(new LLMenuItemToggleGL("Debug Clicks", &gDebugClicks));
01158         menu->append(new LLMenuItemToggleGL("Debug Views", &LLView::sDebugRects));
01159         menu->append(new LLMenuItemCheckGL("Show Name Tooltips", toggle_show_xui_names, NULL, check_show_xui_names, NULL));
01160         menu->append(new LLMenuItemToggleGL("Debug Mouse Events", &LLView::sDebugMouseHandling));
01161         menu->append(new LLMenuItemToggleGL("Debug Keys", &LLView::sDebugKeys));
01162         menu->append(new LLMenuItemToggleGL("Debug WindowProc", &gDebugWindowProc));
01163         menu->append(new LLMenuItemToggleGL("Debug Text Editor Tips", &gDebugTextEditorTips));
01164         menu->appendSeparator();
01165         menu->append(new LLMenuItemCheckGL("Show Time", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowTime"));
01166         menu->append(new LLMenuItemCheckGL("Show Render Info", menu_toggle_control, NULL, menu_check_control, (void*)"DebugShowRenderInfo"));
01167         
01168         menu->createJumpKeys();
01169 }
01170 
01171 void init_debug_xui_menu(LLMenuGL* menu)
01172 {
01173         menu->append(new LLMenuItemCallGL("Floater Test...", LLFloaterTest::show));
01174         menu->append(new LLMenuItemCallGL("Export Menus to XML...", handle_export_menus_to_xml));
01175         menu->append(new LLMenuItemCallGL("Edit UI...", LLFloaterEditUI::show));        
01176         menu->append(new LLMenuItemCallGL("Load from XML...", handle_load_from_xml));
01177         menu->append(new LLMenuItemCallGL("Save to XML...", handle_save_to_xml));
01178         menu->append(new LLMenuItemCheckGL("Show XUI Names", toggle_show_xui_names, NULL, check_show_xui_names, NULL));
01179 
01180         //menu->append(new LLMenuItemCallGL("Buy Currency...", handle_buy_currency));
01181         menu->createJumpKeys();
01182 }
01183 
01184 void init_debug_rendering_menu(LLMenuGL* menu)
01185 {
01186         LLMenuGL* sub_menu = NULL;
01187 
01189         //
01190         // Debug menu for types/pools
01191         //
01192         sub_menu = new LLMenuGL("Types");
01193         menu->appendMenu(sub_menu);
01194 
01195         sub_menu->append(new LLMenuItemCheckGL("Simple",
01196                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01197                                                                                         &LLPipeline::hasRenderTypeControl,
01198                                                                                         (void*)LLPipeline::RENDER_TYPE_SIMPLE,  '1', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
01199         sub_menu->append(new LLMenuItemCheckGL("Alpha",
01200                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01201                                                                                         &LLPipeline::hasRenderTypeControl,
01202                                                                                         (void*)LLPipeline::RENDER_TYPE_ALPHA, '2', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
01203         sub_menu->append(new LLMenuItemCheckGL("Tree",
01204                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01205                                                                                         &LLPipeline::hasRenderTypeControl,
01206                                                                                         (void*)LLPipeline::RENDER_TYPE_TREE, '3', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
01207         sub_menu->append(new LLMenuItemCheckGL("Character",
01208                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01209                                                                                         &LLPipeline::hasRenderTypeControl,
01210                                                                                         (void*)LLPipeline::RENDER_TYPE_AVATAR, '4', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
01211         sub_menu->append(new LLMenuItemCheckGL("SurfacePatch",
01212                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01213                                                                                         &LLPipeline::hasRenderTypeControl,
01214                                                                                         (void*)LLPipeline::RENDER_TYPE_TERRAIN, '5', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
01215         sub_menu->append(new LLMenuItemCheckGL("Sky",
01216                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01217                                                                                         &LLPipeline::hasRenderTypeControl,
01218                                                                                         (void*)LLPipeline::RENDER_TYPE_SKY, '6', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
01219         sub_menu->append(new LLMenuItemCheckGL("Water",
01220                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01221                                                                                         &LLPipeline::hasRenderTypeControl,
01222                                                                                         (void*)LLPipeline::RENDER_TYPE_WATER, '7', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
01223         sub_menu->append(new LLMenuItemCheckGL("Ground",
01224                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01225                                                                                         &LLPipeline::hasRenderTypeControl,
01226                                                                                         (void*)LLPipeline::RENDER_TYPE_GROUND, '8', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
01227         sub_menu->append(new LLMenuItemCheckGL("Volume",
01228                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01229                                                                                         &LLPipeline::hasRenderTypeControl,
01230                                                                                         (void*)LLPipeline::RENDER_TYPE_VOLUME, '9', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
01231         sub_menu->append(new LLMenuItemCheckGL("Grass",
01232                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01233                                                                                         &LLPipeline::hasRenderTypeControl,
01234                                                                                         (void*)LLPipeline::RENDER_TYPE_GRASS, '0', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
01235         sub_menu->append(new LLMenuItemCheckGL("Clouds",
01236                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01237                                                                                         &LLPipeline::hasRenderTypeControl,
01238                                                                                         (void*)LLPipeline::RENDER_TYPE_CLOUDS, '-', MASK_CONTROL|MASK_ALT| MASK_SHIFT));
01239         sub_menu->append(new LLMenuItemCheckGL("Particles",
01240                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01241                                                                                         &LLPipeline::hasRenderTypeControl,
01242                                                                                         (void*)LLPipeline::RENDER_TYPE_PARTICLES, '=', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
01243         sub_menu->append(new LLMenuItemCheckGL("Bump",
01244                                                                                         &LLPipeline::toggleRenderTypeControl, NULL,
01245                                                                                         &LLPipeline::hasRenderTypeControl,
01246                                                                                         (void*)LLPipeline::RENDER_TYPE_BUMP, '\\', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
01247         sub_menu->createJumpKeys();
01248         sub_menu = new LLMenuGL("Features");
01249         menu->appendMenu(sub_menu);
01250         sub_menu->append(new LLMenuItemCheckGL("UI",
01251                                                                                         &LLPipeline::toggleRenderDebugFeature, NULL,
01252                                                                                         &LLPipeline::toggleRenderDebugFeatureControl,
01253                                                                                         (void*)LLPipeline::RENDER_DEBUG_FEATURE_UI, KEY_F1, MASK_ALT|MASK_CONTROL));
01254         sub_menu->append(new LLMenuItemCheckGL("Selected",
01255                                                                                         &LLPipeline::toggleRenderDebugFeature, NULL,
01256                                                                                         &LLPipeline::toggleRenderDebugFeatureControl,
01257                                                                                         (void*)LLPipeline::RENDER_DEBUG_FEATURE_SELECTED, KEY_F2, MASK_ALT|MASK_CONTROL));
01258         sub_menu->append(new LLMenuItemCheckGL("Highlighted",
01259                                                                                         &LLPipeline::toggleRenderDebugFeature, NULL,
01260                                                                                         &LLPipeline::toggleRenderDebugFeatureControl,
01261                                                                                         (void*)LLPipeline::RENDER_DEBUG_FEATURE_HIGHLIGHTED, KEY_F3, MASK_ALT|MASK_CONTROL));
01262         sub_menu->append(new LLMenuItemCheckGL("Dynamic Textures",
01263                                                                                         &LLPipeline::toggleRenderDebugFeature, NULL,
01264                                                                                         &LLPipeline::toggleRenderDebugFeatureControl,
01265                                                                                         (void*)LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES, KEY_F4, MASK_ALT|MASK_CONTROL));
01266         sub_menu->append(new LLMenuItemCheckGL( "Foot Shadows", 
01267                                                                                         &LLPipeline::toggleRenderDebugFeature, NULL,
01268                                                                                         &LLPipeline::toggleRenderDebugFeatureControl,
01269                                                                                         (void*)LLPipeline::RENDER_DEBUG_FEATURE_FOOT_SHADOWS, KEY_F5, MASK_ALT|MASK_CONTROL));
01270         sub_menu->append(new LLMenuItemCheckGL("Fog",
01271                                                                                         &LLPipeline::toggleRenderDebugFeature, NULL,
01272                                                                                         &LLPipeline::toggleRenderDebugFeatureControl,
01273                                                                                         (void*)LLPipeline::RENDER_DEBUG_FEATURE_FOG, KEY_F6, MASK_ALT|MASK_CONTROL));
01274         sub_menu->append(new LLMenuItemCheckGL("Palletized Textures",
01275                                                                                         &LLPipeline::toggleRenderDebugFeature, NULL,
01276                                                                                         &LLPipeline::toggleRenderDebugFeatureControl,
01277                                                                                         (void*)LLPipeline::RENDER_DEBUG_FEATURE_PALETTE, KEY_F7, MASK_ALT|MASK_CONTROL));
01278         sub_menu->append(new LLMenuItemCheckGL("Test FRInfo",
01279                                                                                         &LLPipeline::toggleRenderDebugFeature, NULL,
01280                                                                                         &LLPipeline::toggleRenderDebugFeatureControl,
01281                                                                                         (void*)LLPipeline::RENDER_DEBUG_FEATURE_FR_INFO, KEY_F8, MASK_ALT|MASK_CONTROL));
01282         sub_menu->append(new LLMenuItemCheckGL( "Flexible Objects", 
01283                                                                                         &LLPipeline::toggleRenderDebugFeature, NULL,
01284                                                                                         &LLPipeline::toggleRenderDebugFeatureControl,
01285                                                                                         (void*)LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE, KEY_F9, MASK_ALT|MASK_CONTROL));
01286         sub_menu->createJumpKeys();
01287 
01289         //
01290         // Debug menu for info displays
01291         //
01292         sub_menu = new LLMenuGL("Info Displays");
01293         menu->appendMenu(sub_menu);
01294 
01295         sub_menu->append(new LLMenuItemCheckGL("Verify",        &LLPipeline::toggleRenderDebug, NULL,
01296                                                                                                         &LLPipeline::toggleRenderDebugControl,
01297                                                                                                         (void*)LLPipeline::RENDER_DEBUG_VERIFY));
01298         sub_menu->append(new LLMenuItemCheckGL("BBoxes",        &LLPipeline::toggleRenderDebug, NULL,
01299                                                                                                         &LLPipeline::toggleRenderDebugControl,
01300                                                                                                         (void*)LLPipeline::RENDER_DEBUG_BBOXES));
01301         sub_menu->append(new LLMenuItemCheckGL("Points",        &LLPipeline::toggleRenderDebug, NULL,
01302                                                                                                         &LLPipeline::toggleRenderDebugControl,
01303                                                                                                         (void*)LLPipeline::RENDER_DEBUG_POINTS));
01304         sub_menu->append(new LLMenuItemCheckGL("Octree",        &LLPipeline::toggleRenderDebug, NULL,
01305                                                                                                         &LLPipeline::toggleRenderDebugControl,
01306                                                                                                         (void*)LLPipeline::RENDER_DEBUG_OCTREE));
01307         sub_menu->append(new LLMenuItemCheckGL("Occlusion",     &LLPipeline::toggleRenderDebug, NULL,
01308                                                                                                         &LLPipeline::toggleRenderDebugControl,
01309                                                                                                         (void*)LLPipeline::RENDER_DEBUG_OCCLUSION));
01310         sub_menu->append(new LLMenuItemCheckGL("Animated Textures",     &LLPipeline::toggleRenderDebug, NULL,
01311                                                                                                         &LLPipeline::toggleRenderDebugControl,
01312                                                                                                         (void*)LLPipeline::RENDER_DEBUG_TEXTURE_ANIM));
01313         sub_menu->append(new LLMenuItemCheckGL("Texture Priority",      &LLPipeline::toggleRenderDebug, NULL,
01314                                                                                                         &LLPipeline::toggleRenderDebugControl,
01315                                                                                                         (void*)LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY));
01316         sub_menu->append(new LLMenuItemCheckGL("Texture Area (sqrt(A))",&LLPipeline::toggleRenderDebug, NULL,
01317                                                                                                         &LLPipeline::toggleRenderDebugControl,
01318                                                                                                         (void*)LLPipeline::RENDER_DEBUG_TEXTURE_AREA));
01319         sub_menu->append(new LLMenuItemCheckGL("Face Area (sqrt(A))",&LLPipeline::toggleRenderDebug, NULL,
01320                                                                                                         &LLPipeline::toggleRenderDebugControl,
01321                                                                                                         (void*)LLPipeline::RENDER_DEBUG_FACE_AREA));
01322         sub_menu->append(new LLMenuItemCheckGL("Pick Render",   &LLPipeline::toggleRenderDebug, NULL,
01323                                                                                                         &LLPipeline::toggleRenderDebugControl,
01324                                                                                                         (void*)LLPipeline::RENDER_DEBUG_PICKING));
01325         sub_menu->append(new LLMenuItemCheckGL("Particles",     &LLPipeline::toggleRenderDebug, NULL,
01326                                                                                                         &LLPipeline::toggleRenderDebugControl,
01327                                                                                                         (void*)LLPipeline::RENDER_DEBUG_PARTICLES));
01328         sub_menu->append(new LLMenuItemCheckGL("Composition", &LLPipeline::toggleRenderDebug, NULL,
01329                                                                                                         &LLPipeline::toggleRenderDebugControl,
01330                                                                                                         (void*)LLPipeline::RENDER_DEBUG_COMPOSITION));
01331         sub_menu->append(new LLMenuItemCheckGL("ShadowMap", &LLPipeline::toggleRenderDebug, NULL,
01332                                                                                                         &LLPipeline::toggleRenderDebugControl,
01333                                                                                                         (void*)LLPipeline::RENDER_DEBUG_SHADOW_MAP));
01334         sub_menu->append(new LLMenuItemCheckGL("LightTrace",&LLPipeline::toggleRenderDebug, NULL,
01335                                                                                                         &LLPipeline::toggleRenderDebugControl,
01336                                                                                                         (void*)LLPipeline::RENDER_DEBUG_LIGHT_TRACE));
01337         sub_menu->append(new LLMenuItemCheckGL("Glow",&LLPipeline::toggleRenderDebug, NULL,
01338                                                                                                         &LLPipeline::toggleRenderDebugControl,
01339                                                                                                         (void*)LLPipeline::RENDER_DEBUG_GLOW));
01340         
01341         sub_menu->append(new LLMenuItemCheckGL("Show Depth Buffer",
01342                                                                                    &menu_toggle_control,
01343                                                                                    NULL,
01344                                                                                    &menu_check_control,
01345                                                                                    (void*)"ShowDepthBuffer"));
01346         sub_menu->append(new LLMenuItemToggleGL("Show Select Buffer", &gDebugSelect));
01347 
01348         sub_menu->append(new LLMenuItemToggleGL("Vectorize Perf Test", &gVectorizePerfTest));
01349 
01350         sub_menu = new LLMenuGL("Render Tests");
01351 
01352         sub_menu->append(new LLMenuItemCheckGL("Camera Offset", 
01353                                                                                   &menu_toggle_control,
01354                                                                                   NULL, 
01355                                                                                   &menu_check_control,
01356                                                                                   (void*)"CameraOffset"));
01357 
01358         sub_menu->append(new LLMenuItemToggleGL("Randomize Framerate", &gRandomizeFramerate));
01359 
01360         sub_menu->append(new LLMenuItemToggleGL("Periodic Slow Frame", &gPeriodicSlowFrame));
01361         sub_menu->createJumpKeys();
01362 
01363         menu->appendMenu( sub_menu );
01364 
01365         menu->appendSeparator();
01366         menu->append(new LLMenuItemCheckGL("Axes", menu_toggle_control, NULL, menu_check_control, (void*)"ShowAxes"));
01367 //      menu->append(new LLMenuItemCheckGL("Cull Small Objects", toggle_cull_small, NULL, menu_check_control, (void*)"RenderCullBySize"));
01368 
01369         menu->appendSeparator();
01370         menu->append(new LLMenuItemToggleGL("Hide Selected", &gHideSelectedObjects));
01371         menu->appendSeparator();
01372         menu->append(new LLMenuItemCheckGL("Tangent Basis", menu_toggle_control, NULL, menu_check_control, (void*)"ShowTangentBasis"));
01373         menu->append(new LLMenuItemCallGL("Selected Texture Info", handle_selected_texture_info, NULL, NULL, 'T', MASK_CONTROL|MASK_SHIFT|MASK_ALT));
01374         //menu->append(new LLMenuItemCallGL("Dump Image List", handle_dump_image_list, NULL, NULL, 'I', MASK_CONTROL|MASK_SHIFT));
01375         
01376         menu->append(new LLMenuItemToggleGL("Wireframe", &gUseWireframe, 
01377                         'R', MASK_CONTROL|MASK_SHIFT));
01378 
01379         LLMenuItemCheckGL* item;
01380         item = new LLMenuItemCheckGL("Object-Object Occlusion", menu_toggle_control, NULL, menu_check_control, (void*)"UseOcclusion", 'O', MASK_CONTROL|MASK_SHIFT);
01381         item->setEnabled(gGLManager.mHasOcclusionQuery && gFeatureManagerp->isFeatureAvailable("UseOcclusion"));
01382         menu->append(item);
01383         
01384         
01385         item = new LLMenuItemCheckGL("Animate Textures", menu_toggle_control, NULL, menu_check_control, (void*)"AnimateTextures");
01386         menu->append(item);
01387         
01388         item = new LLMenuItemCheckGL("Disable Textures", menu_toggle_variable, NULL, menu_check_variable, (void*)&LLViewerImage::sDontLoadVolumeTextures);
01389         menu->append(item);
01390         
01391 #ifndef LL_RELEASE_FOR_DOWNLOAD
01392         item = new LLMenuItemCheckGL("HTTP Get Textures", menu_toggle_control, NULL, menu_check_control, (void*)"ImagePipelineUseHTTP");
01393         menu->append(item);
01394 #endif
01395         
01396         item = new LLMenuItemCheckGL("Run Multiple Threads", menu_toggle_control, NULL, menu_check_control, (void*)"RunMultipleThreads");
01397         menu->append(item);
01398 
01399 #ifndef LL_RELEASE_FOR_DOWNLOAD
01400         item = new LLMenuItemCheckGL("Dynamic Reflections", menu_toggle_control, NULL, menu_check_control, (void*)"RenderDynamicReflections");
01401         menu->append(item);
01402 #endif
01403         
01404         item = new LLMenuItemCheckGL("Cheesy Beacon", menu_toggle_control, NULL, menu_check_control, (void*)"CheesyBeacon");
01405         menu->append(item);
01406         
01407         menu->createJumpKeys();
01408 }
01409 
01410 extern BOOL gDebugAvatarRotation;
01411 
01412 void init_debug_avatar_menu(LLMenuGL* menu)
01413 {
01414         LLMenuGL* sub_menu = new LLMenuGL("Grab Baked Texture");
01415         init_debug_baked_texture_menu(sub_menu);
01416         menu->appendMenu(sub_menu);
01417 
01418         sub_menu = new LLMenuGL("Character Tests");
01419         sub_menu->append(new LLMenuItemToggleGL("Go Away/AFK When Idle",
01420                 &gAllowIdleAFK));
01421 
01422         sub_menu->append(new LLMenuItemCallGL("Appearance To XML", 
01423                 &LLVOAvatar::dumpArchetypeXML));
01424 
01425         // HACK for easy testing of avatar geometry
01426         sub_menu->append(new LLMenuItemCallGL( "Toggle Character Geometry", 
01427                 &handle_god_request_avatar_geometry, &enable_god_customer_service, NULL));
01428 
01429         sub_menu->append(new LLMenuItemCallGL("Test Male", 
01430                 handle_test_male));
01431 
01432         sub_menu->append(new LLMenuItemCallGL("Test Female", 
01433                 handle_test_female));
01434 
01435         sub_menu->append(new LLMenuItemCallGL("Toggle PG", handle_toggle_pg));
01436 
01437         sub_menu->append(new LLMenuItemToggleGL("Allow Select Avatar", &gAllowSelectAvatar));
01438         sub_menu->createJumpKeys();
01439 
01440         menu->appendMenu(sub_menu);
01441 
01442         menu->append(new LLMenuItemCallGL("Force Params to Default", &LLAgent::clearVisualParams, NULL));
01443         menu->append(new LLMenuItemCallGL("Reload Vertex Shader", &reload_vertex_shader, NULL));
01444         menu->append(new LLMenuItemToggleGL("Animation Info", &LLVOAvatar::sShowAnimationDebug));
01445         menu->append(new LLMenuItemCallGL("Slow Motion Animations", &slow_mo_animations, NULL));
01446         menu->append(new LLMenuItemToggleGL("Show Look At", &LLHUDEffectLookAt::sDebugLookAt));
01447         menu->append(new LLMenuItemToggleGL("Show Point At", &LLHUDEffectPointAt::sDebugPointAt));
01448         menu->append(new LLMenuItemToggleGL("Debug Joint Updates", &LLVOAvatar::sJointDebug));
01449         menu->append(new LLMenuItemToggleGL("Disable LOD", &LLViewerJoint::sDisableLOD));
01450         menu->append(new LLMenuItemToggleGL("Debug Character Vis", &LLVOAvatar::sDebugInvisible));
01451         //menu->append(new LLMenuItemToggleGL("Show Attachment Points", &LLVOAvatar::sShowAttachmentPoints));
01452         menu->append(new LLMenuItemToggleGL("Show Collision Plane", &LLVOAvatar::sShowFootPlane));
01453         menu->append(new LLMenuItemToggleGL("Show Collision Skeleton", &LLVOAvatar::sShowCollisionVolumes));
01454         menu->append(new LLMenuItemToggleGL( "Display Agent Target", &LLAgent::sDebugDisplayTarget));
01455         menu->append(new LLMenuItemToggleGL( "Debug Rotation", &gDebugAvatarRotation));
01456         menu->append(new LLMenuItemCallGL("Dump Attachments", handle_dump_attachments));
01457         menu->append(new LLMenuItemCallGL("Rebake Textures", handle_rebake_textures, NULL, NULL, 'R', MASK_ALT | MASK_CONTROL ));
01458 #ifndef LL_RELEASE_FOR_DOWNLOAD
01459         menu->append(new LLMenuItemCallGL("Debug Avatar Textures", handle_debug_avatar_textures, NULL, NULL, 'A', MASK_SHIFT|MASK_CONTROL|MASK_ALT));
01460         menu->append(new LLMenuItemCallGL("Dump Local Textures", handle_dump_avatar_local_textures, NULL, NULL, 'M', MASK_SHIFT|MASK_ALT ));    
01461 #endif
01462         menu->createJumpKeys();
01463 }
01464 
01465 void init_debug_baked_texture_menu(LLMenuGL* menu)
01466 {
01467         menu->append(new LLMenuItemCallGL("Iris", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_EYES_BAKED));
01468         menu->append(new LLMenuItemCallGL("Head", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_HEAD_BAKED));
01469         menu->append(new LLMenuItemCallGL("Upper Body", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_UPPER_BAKED));
01470         menu->append(new LLMenuItemCallGL("Lower Body", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_LOWER_BAKED));
01471         menu->append(new LLMenuItemCallGL("Skirt", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_SKIRT_BAKED));
01472         menu->createJumpKeys();
01473 }
01474 
01475 void init_server_menu(LLMenuGL* menu)
01476 {
01477         /*
01478         {
01479                 // These messages are now trusted. We can write scripts to do
01480                 // this, and the message is unchecked for source.
01481                 LLMenuGL* sub_menu = NULL;
01482                 sub_menu = new LLMenuGL("Sim Logging");
01483 
01484                 sub_menu->append(new LLMenuItemCallGL("Turn off llinfos Log", 
01485                         &handle_reduce_llinfo_log, &enable_god_customer_service));
01486 
01487                 sub_menu->append(new LLMenuItemCallGL("Normal Logging", 
01488                         &handle_normal_llinfo_log, &enable_god_customer_service));
01489 
01490                 sub_menu->appendSeparator();
01491                 sub_menu->append(new LLMenuItemCallGL("Enable Message Log",  
01492                         &handle_sim_enable_message_log,  &enable_god_customer_service));
01493                 sub_menu->append(new LLMenuItemCallGL("Disable Message Log", 
01494                         &handle_sim_disable_message_log, &enable_god_customer_service));
01495 
01496                 sub_menu->appendSeparator();
01497 
01498                 sub_menu->append(new LLMenuItemCallGL("Fetch Message Log",      
01499                         &handle_sim_fetch_message_log,  &enable_god_customer_service));
01500 
01501                 sub_menu->append(new LLMenuItemCallGL("Fetch Log",                      
01502                         &handle_sim_fetch_log, &enable_god_customer_service));
01503 
01504                 menu->appendMenu( sub_menu );
01505         }
01506         */
01507 
01508         {
01509                 LLMenuGL* sub = new LLMenuGL("Object");
01510                 menu->appendMenu(sub);
01511 
01512                 sub->append(new LLMenuItemCallGL( "Take Copy",
01513                                                                                   &force_take_copy, &enable_god_customer_service, NULL,
01514                                                                                   'O', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
01515 #ifdef _CORY_TESTING
01516                 sub->append(new LLMenuItemCallGL( "Export Copy",
01517                                                                                    &force_export_copy, NULL, NULL));
01518                 sub->append(new LLMenuItemCallGL( "Import Geometry",
01519                                                                                    &force_import_geometry, NULL, NULL));
01520 #endif
01521                 //sub->append(new LLMenuItemCallGL( "Force Public", 
01522                 //                      &handle_object_owner_none, NULL, NULL));
01523                 //sub->append(new LLMenuItemCallGL( "Force Ownership/Permissive", 
01524                 //                      &handle_object_owner_self_and_permissive, NULL, NULL, 'K', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
01525                 sub->append(new LLMenuItemCallGL( "Force Owner To Me", 
01526                                         &handle_object_owner_self, &enable_god_customer_service));
01527                 sub->append(new LLMenuItemCallGL( "Force Owner Permissive", 
01528                                         &handle_object_owner_permissive, &enable_god_customer_service));
01529                 //sub->append(new LLMenuItemCallGL( "Force Totally Permissive", 
01530                 //                      &handle_object_permissive));
01531                 sub->append(new LLMenuItemCallGL( "Delete", 
01532                                         &handle_force_delete, &enable_god_customer_service, NULL, KEY_DELETE, MASK_SHIFT | MASK_ALT | MASK_CONTROL));
01533                 sub->append(new LLMenuItemCallGL( "Lock", 
01534                                         &handle_object_lock, &enable_god_customer_service, NULL, 'L', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
01535                 sub->append(new LLMenuItemCallGL( "Get Asset IDs", 
01536                                         &handle_object_asset_ids, &enable_god_customer_service, NULL, 'I', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
01537                 sub->createJumpKeys();
01538         }
01539         {
01540                 LLMenuGL* sub = new LLMenuGL("Parcel");
01541                 menu->appendMenu(sub);
01542 
01543                 sub->append(new LLMenuItemCallGL("Owner To Me",
01544                                                                                  &handle_force_parcel_owner_to_me,
01545                                                                                  &enable_god_customer_service, NULL));
01546                 sub->append(new LLMenuItemCallGL("Set to Linden Content",
01547                                                                                  &handle_force_parcel_to_content,
01548                                                                                  &enable_god_customer_service, NULL,
01549                                                                                  'C', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
01550                 sub->appendSeparator();
01551                 sub->append(new LLMenuItemCallGL("Claim Public Land",
01552                                                                                  &handle_claim_public_land, &enable_god_customer_service));
01553 
01554                 sub->createJumpKeys();
01555         }
01556         {
01557                 LLMenuGL* sub = new LLMenuGL("Region");
01558                 menu->appendMenu(sub);
01559                 sub->append(new LLMenuItemCallGL("Dump Temp Asset Data",
01560                         &handle_region_dump_temp_asset_data,
01561                         &enable_god_customer_service, NULL));
01562                 sub->createJumpKeys();
01563         }       
01564         menu->append(new LLMenuItemCallGL( "God Tools...", 
01565                 &LLFloaterGodTools::show, &enable_god_basic, NULL));
01566 
01567         menu->appendSeparator();
01568 
01569         menu->append(new LLMenuItemCallGL("Save Region State", 
01570                 &LLPanelRegionTools::onSaveState, &enable_god_customer_service, NULL));
01571 
01572 //      menu->append(new LLMenuItemCallGL("Force Join Group", handle_force_join_group));
01573 
01574 
01575 
01576         menu->appendSeparator();
01577 //
01578 //      menu->append(new LLMenuItemCallGL( "OverlayTitle",
01579 //              &handle_show_overlay_title, &enable_god_customer_service, NULL));
01580 
01581         menu->append(new LLMenuItemCallGL("Request Admin Status", 
01582                 &handle_god_mode, NULL, NULL, 'G', MASK_ALT | MASK_CONTROL));
01583 
01584         menu->append(new LLMenuItemCallGL("Leave Admin Status", 
01585                 &handle_leave_god_mode, NULL, NULL, 'G', MASK_ALT | MASK_SHIFT | MASK_CONTROL));
01586         menu->createJumpKeys();
01587 }
01588 
01589 static std::vector<LLPointer<view_listener_t> > sMenus;
01590 
01591 //-----------------------------------------------------------------------------
01592 // cleanup_menus()
01593 //-----------------------------------------------------------------------------
01594 void cleanup_menus()
01595 {
01596         clear_landmark_menu(gLandmarkMenu);
01597 
01598         delete gMenuParcelObserver;
01599         gMenuParcelObserver = NULL;
01600 
01601         delete gLandmarkObserver;
01602         gLandmarkObserver = NULL;
01603 
01604         delete gPieSelf;
01605         gPieSelf = NULL;
01606 
01607         delete gPieAvatar;
01608         gPieAvatar = NULL;
01609 
01610         delete gPieObject;
01611         gPieObject = NULL;
01612 
01613         delete gPieAttachment;
01614         gPieAttachment = NULL;
01615 
01616         delete gPieLand;
01617         gPieLand = NULL;
01618 
01619         delete gMenuBarView;
01620         gMenuBarView = NULL;
01621 
01622         delete gPopupMenuView;
01623         gPopupMenuView = NULL;
01624 
01625         delete gMenuHolder;
01626         gMenuHolder = NULL;
01627 
01628         sMenus.clear();
01629 }
01630 
01631 //-----------------------------------------------------------------------------
01632 // Object pie menu
01633 //-----------------------------------------------------------------------------
01634 
01635 class LLObjectReportAbuse : public view_listener_t
01636 {
01637         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01638         {
01639                 LLFloaterReporter::showFromObject(gLastHitObjectID);
01640                 return true;
01641         }
01642 };
01643 
01644 // Enabled it you clicked an object
01645 class LLObjectEnableReportAbuse : public view_listener_t
01646 {
01647         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01648         {
01649                 bool new_value = !gLastHitObjectID.isNull();
01650                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
01651                 return true;
01652         }
01653 };
01654 
01655 class LLObjectTouch : public view_listener_t
01656 {
01657         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01658         {
01659                 LLViewerObject* object = gObjectList.findObject(gLastHitObjectID);
01660                 if (!object) return true;
01661 
01662                 LLMessageSystem *msg = gMessageSystem;
01663 
01664                 msg->newMessageFast(_PREHASH_ObjectGrab);
01665                 msg->nextBlockFast( _PREHASH_AgentData);
01666                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
01667                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
01668                 msg->nextBlockFast( _PREHASH_ObjectData);
01669                 msg->addU32Fast(    _PREHASH_LocalID, object->mLocalID);
01670                 msg->addVector3Fast(_PREHASH_GrabOffset, LLVector3::zero );
01671                 msg->sendMessage( object->getRegion()->getHost());
01672 
01673                 // *NOTE: Hope the packets arrive safely and in order or else
01674                 // there will be some problems.
01675                 // *TODO: Just fix this bad assumption.
01676                 msg->newMessageFast(_PREHASH_ObjectDeGrab);
01677                 msg->nextBlockFast(_PREHASH_AgentData);
01678                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
01679                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
01680                 msg->nextBlockFast(_PREHASH_ObjectData);
01681                 msg->addU32Fast(_PREHASH_LocalID, object->mLocalID);
01682                 msg->sendMessage(object->getRegion()->getHost());
01683 
01684                 return true;
01685         }
01686 };
01687 
01688 
01689 // One object must have touch sensor
01690 class LLObjectEnableTouch : public view_listener_t
01691 {
01692         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01693         {
01694                 LLViewerObject* obj = gObjectList.findObject(gLastHitObjectID);
01695                 bool new_value = obj && obj->flagHandleTouch();
01696                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
01697 
01698                 // Update label based on the node touch name if available.
01699                 LLSelectNode* node = gSelectMgr->getSelection()->getFirstRootNode();
01700                 if (node && node->mValid && !node->mTouchName.empty())
01701                 {
01702                         gMenuHolder->childSetText("Object Touch", node->mTouchName);
01703                 }
01704                 else
01705                 {
01706                         gMenuHolder->childSetText("Object Touch", userdata["data"].asString());
01707                 }
01708 
01709                 return true;
01710         }
01711 };
01712 
01713 void label_touch(LLString& label, void*)
01714 {
01715         LLSelectNode* node = gSelectMgr->getSelection()->getFirstRootNode();
01716         if (node && node->mValid && !node->mTouchName.empty())
01717         {
01718                 label.assign(node->mTouchName);
01719         }
01720         else
01721         {
01722                 label.assign("Touch");
01723         }
01724 }
01725 
01726 bool handle_object_open()
01727 {
01728         LLViewerObject* obj = gObjectList.findObject(gLastHitObjectID);
01729         if(!obj) return true;
01730 
01731         LLFloaterOpenObject::show();
01732         return true;
01733 }
01734 
01735 class LLObjectOpen : public view_listener_t
01736 {
01737         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01738         {
01739                 return handle_object_open();
01740         }
01741 };
01742 
01743 class LLObjectEnableOpen : public view_listener_t
01744 {
01745         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01746         {
01747                 // Look for contents in root object, which is all the LLFloaterOpenObject
01748                 // understands.
01749                 LLViewerObject* obj = gObjectList.findObject(gLastHitObjectID);
01750                 bool new_value = (obj != NULL);
01751                 if (new_value)
01752                 {
01753                         LLViewerObject* root = obj->getRootEdit();
01754                         if (!root) new_value = false;
01755                         else new_value = root->allowOpen();
01756                 }
01757                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
01758                 return true;
01759         }
01760 };
01761 
01762 
01763 class LLViewCheckBuildMode : public view_listener_t
01764 {
01765         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01766         {
01767                 bool new_value = gToolMgr->inEdit();
01768                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
01769                 return true;
01770         }
01771 };
01772 
01773 bool toggle_build_mode()
01774 {
01775         if (gToolMgr->inEdit())
01776         {
01777                 // just reset the view, will pull us out of edit mode
01778                 handle_reset_view();
01779         }
01780         else
01781         {
01782                 if (gAgent.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") )
01783                 {
01784                         // zoom in if we're looking at the avatar
01785                         gAgent.setFocusOnAvatar(FALSE, ANIMATE);
01786                         gAgent.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis()));
01787                         gAgent.cameraZoomIn(0.666f);
01788                         gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
01789                 }
01790 
01791                 gToolMgr->setCurrentToolset(gBasicToolset);
01792                 gToolMgr->getCurrentToolset()->selectTool( gToolCreate );
01793 
01794                 // Could be first use
01795                 LLFirstUse::useBuild();
01796         }
01797         return true;
01798 }
01799 
01800 class LLViewBuildMode : public view_listener_t
01801 {
01802         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01803         {
01804                 return toggle_build_mode();
01805         }
01806 };
01807 
01808 
01809 class LLObjectBuild : public view_listener_t
01810 {
01811         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01812         {
01813                 if (gAgent.getFocusOnAvatar() && !gToolMgr->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
01814                 {
01815                         // zoom in if we're looking at the avatar
01816                         gAgent.setFocusOnAvatar(FALSE, ANIMATE);
01817                         gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
01818                         gAgent.cameraZoomIn(0.666f);
01819                         gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
01820                         gViewerWindow->moveCursorToCenter();
01821                 }
01822                 else if ( gSavedSettings.getBOOL("EditCameraMovement") )
01823                 {
01824                         gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
01825                         gViewerWindow->moveCursorToCenter();
01826                 }
01827 
01828                 gToolMgr->setCurrentToolset(gBasicToolset);
01829                 gToolMgr->getCurrentToolset()->selectTool( gToolCreate );
01830 
01831                 // Could be first use
01832                 LLFirstUse::useBuild();
01833                 return true;
01834         }
01835 };
01836 
01837 class LLObjectEdit : public view_listener_t
01838 {
01839         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01840         {
01841                 gParcelMgr->deselectLand();
01842 
01843                 if (gAgent.getFocusOnAvatar() && !gToolMgr->inEdit())
01844                 {
01845                         LLObjectSelectionHandle selection = gSelectMgr->getSelection();
01846 
01847                         if (selection->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement"))
01848                         {
01849                                 // always freeze camera in space, even if camera doesn't move
01850                                 // so, for example, follow cam scripts can't affect you when in build mode
01851                                 gAgent.setFocusGlobal(gAgent.calcFocusPositionTargetGlobal(), LLUUID::null);
01852                                 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
01853                         }
01854                         else
01855                         {
01856                                 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
01857                                 // zoom in on object center instead of where we clicked, as we need to see the manipulator handles
01858                                 gAgent.setFocusGlobal(gLastHitPosGlobal /*+ gLastHitObjectOffset*/, gLastHitObjectID);
01859                                 gAgent.cameraZoomIn(0.666f);
01860                                 gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
01861                                 gViewerWindow->moveCursorToCenter();
01862                         }
01863                 }
01864 
01865                 gFloaterTools->open();          /* Flawfinder: ignore */
01866         
01867                 gToolMgr->setCurrentToolset(gBasicToolset);
01868                 gFloaterTools->setEditTool( gToolTranslate );
01869 
01870                 // Could be first use
01871                 LLFirstUse::useBuild();
01872                 return true;
01873         }
01874 };
01875 
01876 class LLObjectInspect : public view_listener_t
01877 {
01878         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01879         {
01880                 LLFloaterInspect::show();
01881                 return true;
01882         }
01883 };
01884 
01885 
01886 //---------------------------------------------------------------------------
01887 // Land pie menu
01888 //---------------------------------------------------------------------------
01889 class LLLandBuild : public view_listener_t
01890 {
01891         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01892         {
01893                 gParcelMgr->deselectLand();
01894 
01895                 if (gAgent.getFocusOnAvatar() && !gToolMgr->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
01896                 {
01897                         // zoom in if we're looking at the avatar
01898                         gAgent.setFocusOnAvatar(FALSE, ANIMATE);
01899                         gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
01900                         gAgent.cameraZoomIn(0.666f);
01901                         gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
01902                         gViewerWindow->moveCursorToCenter();
01903                 }
01904                 else if ( gSavedSettings.getBOOL("EditCameraMovement")  )
01905                 {
01906                         // otherwise just move focus
01907                         gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
01908                         gViewerWindow->moveCursorToCenter();
01909                 }
01910 
01911 
01912                 gToolMgr->setCurrentToolset(gBasicToolset);
01913                 gToolMgr->getCurrentToolset()->selectTool( gToolCreate );
01914 
01915                 // Could be first use
01916                 LLFirstUse::useBuild();
01917                 return true;
01918         }
01919 };
01920 
01921 class LLLandBuyPass : public view_listener_t
01922 {
01923         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01924         {
01925                 LLPanelLandGeneral::onClickBuyPass((void *)FALSE);
01926                 return true;
01927         }
01928 };
01929 
01930 class LLLandEnableBuyPass : public view_listener_t
01931 {
01932         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01933         {
01934                 bool new_value = LLPanelLandGeneral::enableBuyPass(NULL);
01935                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
01936                 return true;
01937         }
01938 };
01939 
01940 // BUG: Should really check if CLICK POINT is in a parcel where you can build.
01941 BOOL enable_land_build(void*)
01942 {
01943         if (gAgent.isGodlike()) return TRUE;
01944         if (gAgent.inPrelude()) return FALSE;
01945 
01946         BOOL can_build = FALSE;
01947         LLParcel* agent_parcel = gParcelMgr->getAgentParcel();
01948         if (agent_parcel)
01949         {
01950                 can_build = agent_parcel->getAllowModify();
01951         }
01952         return can_build;
01953 }
01954 
01955 // BUG: Should really check if OBJECT is in a parcel where you can build.
01956 BOOL enable_object_build(void*)
01957 {
01958         if (gAgent.isGodlike()) return TRUE;
01959         if (gAgent.inPrelude()) return FALSE;
01960 
01961         BOOL can_build = FALSE;
01962         LLParcel* agent_parcel = gParcelMgr->getAgentParcel();
01963         if (agent_parcel)
01964         {
01965                 can_build = agent_parcel->getAllowModify();
01966         }
01967         return can_build;
01968 }
01969 
01970 class LLEnableEdit : public view_listener_t
01971 {
01972         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01973         {
01974                 bool new_value = gAgent.isGodlike() || !gAgent.inPrelude();
01975                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
01976                 return true;
01977         }
01978 };
01979 
01980 class LLSelfRemoveAllAttachments : public view_listener_t
01981 {
01982         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01983         {
01984                 LLAgent::userRemoveAllAttachments(NULL);
01985                 return true;
01986         }
01987 };
01988 
01989 class LLSelfEnableRemoveAllAttachments : public view_listener_t
01990 {
01991         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
01992         {
01993                 bool new_value = false;
01994                 if (gAgent.getAvatarObject())
01995                 {
01996                         LLVOAvatar* avatarp = gAgent.getAvatarObject();
01997                         for (LLViewerJointAttachment* attachmentp = avatarp->mAttachmentPoints.getFirstData();
01998                                 attachmentp;
01999                                 attachmentp = avatarp->mAttachmentPoints.getNextData())
02000                         {
02001                                 if (attachmentp->getObject())
02002                                 {
02003                                         new_value = true;
02004                                         break;
02005                                 }
02006                         }
02007                 }
02008                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
02009                 return true;
02010         }
02011 };
02012 
02013 BOOL enable_has_attachments(void*)
02014 {
02015 
02016         return FALSE;
02017 }
02018 
02019 //---------------------------------------------------------------------------
02020 // Avatar pie menu
02021 //---------------------------------------------------------------------------
02022 void handle_follow(void *userdata)
02023 {
02024         // follow a given avatar, ID in gLastHitObjectID
02025         gAgent.startFollowPilot(gLastHitObjectID);
02026 }
02027 
02028 class LLObjectEnableMute : public view_listener_t
02029 {
02030         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02031         {
02032                 LLViewerObject* object = gViewerWindow->lastObjectHit();
02033                 bool new_value = (object != NULL);
02034                 if (new_value)
02035                 {
02036                         LLVOAvatar* avatar = find_avatar_from_object(object); 
02037                         if (avatar)
02038                         {
02039                                 // It's an avatar
02040                                 LLNameValue *lastname = avatar->getNVPair("LastName");
02041                                 BOOL is_linden = lastname && !LLString::compareStrings(lastname->getString(), "Linden");
02042                                 BOOL is_self = avatar->isSelf();
02043                                 new_value = !is_linden && !is_self;
02044                         }
02045                 }
02046                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
02047                 return true;
02048         }
02049 };
02050 
02051 class LLObjectMute : public view_listener_t
02052 {
02053         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02054         {
02055                 LLViewerObject* object = gViewerWindow->lastObjectHit();
02056                 if (!object) return true;
02057                 
02058                 LLUUID id;
02059                 LLString name;
02060                 LLMute::EType type;
02061                 LLVOAvatar* avatar = find_avatar_from_object(object); 
02062                 if (avatar)
02063                 {
02064                         id = avatar->getID();
02065 
02066                         LLNameValue *firstname = avatar->getNVPair("FirstName");
02067                         LLNameValue *lastname = avatar->getNVPair("LastName");
02068                         if (firstname && lastname)
02069                         {
02070                                 name = firstname->getString();
02071                                 name += " ";
02072                                 name += lastname->getString();
02073                         }
02074                         
02075                         type = LLMute::AGENT;
02076                 }
02077                 else
02078                 {
02079                         // it's an object
02080                         id = object->getID();
02081 
02082                         LLSelectNode* node = gSelectMgr->getSelection()->getFirstRootNode();
02083                         if (node)
02084                         {
02085                                 name = node->mName;
02086                         }
02087                         
02088                         type = LLMute::OBJECT;
02089                 }
02090                 
02091                 LLMute mute(id, name, type);
02092                 if (gMuteListp->isMuted(mute.mID, mute.mName))
02093                 {
02094                         gMuteListp->remove(mute);
02095                 }
02096                 else
02097                 {
02098                         gMuteListp->add(mute);
02099                         gFloaterMute->show();
02100                 }
02101                 
02102                 return true;
02103         }
02104 };
02105 
02106 bool handle_go_to()
02107 {
02108         // JAMESDEBUG try simulator autopilot
02109         std::vector<std::string> strings;
02110         std::string val;
02111         val = llformat("%g", gLastHitPosGlobal.mdV[VX]);
02112         strings.push_back(val);
02113         val = llformat("%g", gLastHitPosGlobal.mdV[VY]);
02114         strings.push_back(val);
02115         val = llformat("%g", gLastHitPosGlobal.mdV[VZ]);
02116         strings.push_back(val);
02117         send_generic_message("autopilot", strings);
02118 
02119         gParcelMgr->deselectLand();
02120 
02121         if (gAgent.getAvatarObject() && !gSavedSettings.getBOOL("AutoPilotLocksCamera"))
02122         {
02123                 gAgent.setFocusGlobal(gAgent.getFocusTargetGlobal(), gAgent.getAvatarObject()->getID());
02124         }
02125         else 
02126         {
02127                 // Snap camera back to behind avatar
02128                 gAgent.setFocusOnAvatar(TRUE, ANIMATE);
02129         }
02130 
02131         // Could be first use
02132         LLFirstUse::useGoTo();
02133         return true;
02134 }
02135 
02136 class LLGoToObject : public view_listener_t
02137 {
02138         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02139         {
02140                 return handle_go_to();
02141         }
02142 };
02143 
02144 //---------------------------------------------------------------------------
02145 // Parcel freeze, eject, etc.
02146 //---------------------------------------------------------------------------
02147 void callback_freeze(S32 option, void* data)
02148 {
02149         LLUUID* avatar_id = (LLUUID*) data;
02150 
02151         if (0 == option || 1 == option)
02152         {
02153                 U32 flags = 0x0;
02154                 if (1 == option)
02155                 {
02156                         // unfreeze
02157                         flags |= 0x1;
02158                 }
02159 
02160                 LLMessageSystem* msg = gMessageSystem;
02161                 LLViewerObject* avatar = gObjectList.findObject(*avatar_id);
02162 
02163                 if (avatar)
02164                 {
02165                         msg->newMessage("FreezeUser");
02166                         msg->nextBlock("AgentData");
02167                         msg->addUUID("AgentID", gAgent.getID());
02168                         msg->addUUID("SessionID", gAgent.getSessionID());
02169                         msg->nextBlock("Data");
02170                         msg->addUUID("TargetID", *avatar_id );
02171                         msg->addU32("Flags", flags );
02172                         msg->sendReliable( avatar->getRegion()->getHost() );
02173                 }
02174         }
02175 
02176         delete avatar_id;
02177         avatar_id = NULL;
02178 }
02179 
02180 class LLAvatarFreeze : public view_listener_t
02181 {
02182         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02183         {
02184                 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
02185                 if( avatar )
02186                 {
02187                         LLUUID* avatar_id = new LLUUID( avatar->getID() );
02188 
02189                         gViewerWindow->alertXml("FreezeAvatar",
02190                                 callback_freeze, (void*)avatar_id);
02191                         
02192                 }
02193                 return true;
02194         }
02195 };
02196 
02197 class LLAvatarVisibleDebug : public view_listener_t
02198 {
02199         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02200         {
02201                 bool new_value = gAgent.isGodlike();
02202                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
02203                 return true;
02204         }
02205 };
02206 
02207 class LLAvatarEnableDebug : public view_listener_t
02208 {
02209         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02210         {
02211                 bool new_value = gAgent.isGodlike();
02212                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
02213                 return true;
02214         }
02215 };
02216 
02217 class LLAvatarDebug : public view_listener_t
02218 {
02219         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02220         {
02221                 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
02222                 if( avatar )
02223                 {
02224                         avatar->dumpLocalTextures();
02225                         llinfos << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << llendl;
02226                         std::vector<std::string> strings;
02227                         strings.push_back(avatar->getID().asString());
02228                         LLUUID invoice;
02229                         send_generic_message("dumptempassetdata", strings, invoice);
02230                         LLFloaterAvatarTextures::show( avatar->getID() );
02231                 }
02232                 return true;
02233         }
02234 };
02235 
02236 void callback_eject(S32 option, void* data)
02237 {
02238         LLUUID* avatar_id = (LLUUID*) data;
02239 
02240         if (0 == option || 1 == option)
02241         {
02242                 LLMessageSystem* msg = gMessageSystem;
02243                 LLViewerObject* avatar = gObjectList.findObject(*avatar_id);
02244 
02245                 if (avatar)
02246                 {
02247                         U32 flags = 0x0;
02248                         if (1 == option)
02249                         {
02250                                 // eject and add to ban list
02251                                 flags |= 0x1;
02252                         }
02253 
02254                         msg->newMessage("EjectUser");
02255                         msg->nextBlock("AgentData");
02256                         msg->addUUID("AgentID", gAgent.getID() );
02257                         msg->addUUID("SessionID", gAgent.getSessionID() );
02258                         msg->nextBlock("Data");
02259                         msg->addUUID("TargetID", *avatar_id );
02260                         msg->addU32("Flags", flags );
02261                         msg->sendReliable( avatar->getRegion()->getHost() );
02262                 }
02263         }
02264 
02265         delete avatar_id;
02266         avatar_id = NULL;
02267 }
02268 
02269 class LLAvatarEject : public view_listener_t
02270 {
02271         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02272         {
02273                 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
02274                 if( avatar )
02275                 {
02276                         LLUUID* avatar_id = new LLUUID( avatar->getID() );
02277                         gViewerWindow->alertXml("EjectAvatar",
02278                                         callback_eject, (void*)avatar_id);
02279                         
02280                 }
02281                 return true;
02282         }
02283 };
02284 
02285 class LLAvatarEnableFreezeEject : public view_listener_t
02286 {
02287         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02288         {
02289                 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
02290                 bool new_value = (avatar != NULL);
02291 
02292                 if (new_value)
02293                 {
02294                         const LLVector3& pos = avatar->getPositionRegion();
02295                         LLViewerRegion* region = avatar->getRegion();
02296                         new_value = (region != NULL);
02297 
02298                         if (new_value)
02299                         {
02300                                 new_value = (region->isOwnedSelf(pos) || region->isOwnedGroup(pos));
02301                         }
02302                 }
02303 
02304                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
02305                 return true;
02306         }
02307 };
02308 
02309 class LLAvatarGiveCard : public view_listener_t
02310 {
02311         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02312         {
02313                 llinfos << "handle_give_card()" << llendl;
02314                 LLViewerObject* dest = gViewerWindow->lastObjectHit();
02315                 if(dest && dest->isAvatar())
02316                 {
02317                         bool found_name = false;
02318                         LLString::format_map_t args;
02319                         LLNameValue* nvfirst = dest->getNVPair("FirstName");
02320                         LLNameValue* nvlast = dest->getNVPair("LastName");
02321                         if(nvfirst && nvlast)
02322                         {
02323                                 args["[FIRST]"] = nvfirst->getString();
02324                                 args["[LAST]"] = nvlast->getString();
02325                                 found_name = true;
02326                         }
02327                         LLViewerRegion* region = dest->getRegion();
02328                         LLHost dest_host;
02329                         if(region)
02330                         {
02331                                 dest_host = region->getHost();
02332                         }
02333                         if(found_name && dest_host.isOk())
02334                         {
02335                                 LLMessageSystem* msg = gMessageSystem;
02336                                 msg->newMessage("OfferCallingCard");
02337                                 msg->nextBlockFast(_PREHASH_AgentData);
02338                                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02339                                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02340                                 msg->nextBlockFast(_PREHASH_AgentBlock);
02341                                 msg->addUUIDFast(_PREHASH_DestID, dest->getID());
02342                                 LLUUID transaction_id;
02343                                 transaction_id.generate();
02344                                 msg->addUUIDFast(_PREHASH_TransactionID, transaction_id);
02345                                 msg->sendReliable(dest_host);
02346                                 LLNotifyBox::showXml("OfferedCard", args);
02347                         }
02348                         else
02349                         {
02350                                 gViewerWindow->alertXml("CantOfferCallingCard", args);
02351                         }
02352                 }
02353                 return true;
02354         }
02355 };
02356 
02357 
02358 
02359 void login_done(S32 which, void *user)
02360 {
02361         llinfos << "Login done " << which << llendl;
02362 
02363         LLPanelLogin::close();
02364 }
02365 
02366 
02367 void callback_leave_group(S32 option, void *userdata)
02368 {
02369         if (option == 0)
02370         {
02371                 LLMessageSystem *msg = gMessageSystem;
02372 
02373                 msg->newMessageFast(_PREHASH_LeaveGroupRequest);
02374                 msg->nextBlockFast(_PREHASH_AgentData);
02375                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
02376                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02377                 msg->nextBlockFast(_PREHASH_GroupData);
02378                 msg->addUUIDFast(_PREHASH_GroupID, gAgent.mGroupID );
02379                 //msg->sendReliable( gUserServer );
02380                 gAgent.sendReliableMessage();
02381         }
02382 }
02383 
02384 void handle_leave_group(void *)
02385 {
02386         if (gAgent.getGroupID() != LLUUID::null)
02387         {
02388                 LLString::format_map_t args;
02389                 args["[GROUP]"] = gAgent.mGroupName;
02390                 gViewerWindow->alertXml("GroupLeaveConfirmMember", args, callback_leave_group);
02391         }
02392 }
02393 
02394 void append_aggregate(LLString& string, const LLAggregatePermissions& ag_perm, PermissionBit bit, const char* txt)
02395 {
02396         LLAggregatePermissions::EValue val = ag_perm.getValue(bit);
02397         char buffer[MAX_STRING];                /* Flawfinder: ignore */
02398         buffer[0] = '\0';
02399         switch(val)
02400         {
02401         case LLAggregatePermissions::AP_NONE:
02402                 snprintf(buffer, MAX_STRING, "* %s None\n", txt);               /* Flawfinder: ignore */
02403                 break;
02404         case LLAggregatePermissions::AP_SOME:
02405                 snprintf(buffer, MAX_STRING, "* %s Some\n", txt);               /* Flawfinder: ignore */
02406                 break;
02407         case LLAggregatePermissions::AP_ALL:
02408                 snprintf(buffer, MAX_STRING, "* %s All\n", txt);                /* Flawfinder: ignore */
02409                 break;
02410         case LLAggregatePermissions::AP_EMPTY:
02411         default:
02412                 break;
02413         }
02414         string.append(buffer);
02415 }
02416 
02417 const char* build_extensions_string(LLFilePicker::ELoadFilter filter)
02418 {
02419         switch(filter)
02420         {
02421 #if LL_WINDOWS
02422         case LLFilePicker::FFLOAD_IMAGE:
02423                 return IMAGE_EXTENSIONS;
02424         case LLFilePicker::FFLOAD_WAV:
02425                 return SOUND_EXTENSIONS;
02426         case LLFilePicker::FFLOAD_ANIM:
02427                 return ANIM_EXTENSIONS;
02428         case LLFilePicker::FFLOAD_SLOBJECT:
02429                 return SLOBJECT_EXTENSIONS;
02430 #ifdef _CORY_TESTING
02431         case LLFilePicker::FFLOAD_GEOMETRY:
02432                 return GEOMETRY_EXTENSIONS;
02433 #endif
02434         case LLFilePicker::FFLOAD_XML:
02435             return XML_EXTENSIONS;
02436         case LLFilePicker::FFLOAD_ALL:
02437                 return ALL_FILE_EXTENSIONS;
02438 #endif
02439     default:
02440         return ALL_FILE_EXTENSIONS;
02441         }
02442 }
02443 
02444 
02445 BOOL enable_buy(void*)
02446 {
02447     // In order to buy, there must only be 1 purchaseable object in
02448     // the selection manger.
02449         if(gSelectMgr->getSelection()->getRootObjectCount() != 1) return FALSE;
02450     LLViewerObject* obj = NULL;
02451     LLSelectNode* node = gSelectMgr->getSelection()->getFirstRootNode();
02452         if(node)
02453     {
02454         obj = node->getObject();
02455         if(!obj) return FALSE;
02456 
02457                 if(node->mSaleInfo.isForSale() && node->mPermissions->getMaskOwner() & PERM_TRANSFER &&
02458                         (node->mPermissions->getMaskOwner() & PERM_COPY || node->mSaleInfo.getSaleType() != LLSaleInfo::FS_COPY))
02459                 {
02460                         if(obj->permAnyOwner()) return TRUE;
02461                 }
02462     }
02463         return FALSE;
02464 }
02465 
02466 class LLObjectEnableBuy : public view_listener_t
02467 {
02468         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02469         {
02470                 bool new_value = enable_buy(NULL);
02471                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
02472                 return true;
02473         }
02474 };
02475 
02476 // Note: This will only work if the selected object's data has been
02477 // received by the viewer and cached in the selection manager.
02478 void handle_buy_object(LLSaleInfo sale_info)
02479 {
02480         if(!gSelectMgr->selectGetAllRootsValid())
02481         {
02482                 LLNotifyBox::showXml("UnableToBuyWhileDownloading");
02483                 return;
02484         }
02485 
02486         LLUUID owner_id;
02487         LLString owner_name;
02488         BOOL owners_identical = gSelectMgr->selectGetOwner(owner_id, owner_name);
02489         if (!owners_identical)
02490         {
02491                 LLNotifyBox::showXml("CannotBuyObjectsFromDifferentOwners");
02492                 return;
02493         }
02494 
02495         LLPermissions perm;
02496         BOOL valid = gSelectMgr->selectGetPermissions(perm);
02497         LLAggregatePermissions ag_perm;
02498         valid &= gSelectMgr->selectGetAggregatePermissions(ag_perm);
02499         if(!valid || !sale_info.isForSale() || !perm.allowTransferTo(gAgent.getID()))
02500         {
02501                 LLNotifyBox::showXml("ObjectNotForSale");
02502                 return;
02503         }
02504 
02505         S32 price = sale_info.getSalePrice();
02506         
02507         if (price > 0 && price > gStatusBar->getBalance())
02508         {
02509                 LLFloaterBuyCurrency::buyCurrency("This object costs", price);
02510                 return;
02511         }
02512 
02513         LLFloaterBuy::show(sale_info);
02514 }
02515 
02516 
02517 void handle_buy_contents(LLSaleInfo sale_info)
02518 {
02519         LLFloaterBuyContents::show(sale_info);
02520 }
02521 
02522 void handle_region_dump_temp_asset_data(void*)
02523 {
02524         llinfos << "Dumping temporary asset data to simulator logs" << llendl;
02525         std::vector<std::string> strings;
02526         LLUUID invoice;
02527         send_generic_message("dumptempassetdata", strings, invoice);
02528 }
02529 
02530 void handle_region_clear_temp_asset_data(void*)
02531 {
02532         llinfos << "Clearing temporary asset data" << llendl;
02533         std::vector<std::string> strings;
02534         LLUUID invoice;
02535         send_generic_message("cleartempassetdata", strings, invoice);
02536 }
02537 
02538 void handle_region_dump_settings(void*)
02539 {
02540         LLViewerRegion* regionp = gAgent.getRegion();
02541         if (regionp)
02542         {
02543                 llinfos << "Damage:    " << (regionp->getAllowDamage() ? "on" : "off") << llendl;
02544                 llinfos << "Landmark:  " << (regionp->getAllowLandmark() ? "on" : "off") << llendl;
02545                 llinfos << "SetHome:   " << (regionp->getAllowSetHome() ? "on" : "off") << llendl;
02546                 llinfos << "ResetHome: " << (regionp->getResetHomeOnTeleport() ? "on" : "off") << llendl;
02547                 llinfos << "SunFixed:  " << (regionp->getSunFixed() ? "on" : "off") << llendl;
02548                 llinfos << "BlockFly:  " << (regionp->getBlockFly() ? "on" : "off") << llendl;
02549                 llinfos << "AllowP2P:  " << (regionp->getAllowDirectTeleport() ? "on" : "off") << llendl;
02550                 llinfos << "Water:     " << (regionp->getWaterHeight()) << llendl;
02551         }
02552 }
02553 
02554 void handle_dump_group_info(void *)
02555 {
02556         llinfos << "group   " << gAgent.mGroupName << llendl;
02557         llinfos << "ID      " << gAgent.mGroupID << llendl;
02558         llinfos << "powers " << gAgent.mGroupPowers << llendl;
02559         llinfos << "title   " << gAgent.mGroupTitle << llendl;
02560         //llinfos << "insig   " << gAgent.mGroupInsigniaID << llendl;
02561 }
02562 
02563 void handle_dump_capabilities_info(void *)
02564 {
02565         LLViewerRegion* regionp = gAgent.getRegion();
02566         if (regionp)
02567         {
02568                 regionp->logActiveCapabilities();
02569         }
02570 }
02571 
02572 void handle_dump_region_object_cache(void*)
02573 {
02574         LLViewerRegion* regionp = gAgent.getRegion();
02575         if (regionp)
02576         {
02577                 regionp->dumpCache();
02578         }
02579 }
02580 
02581 void handle_dump_focus(void *)
02582 {
02583         LLView *view = gFocusMgr.getKeyboardFocus();
02584 
02585         llinfos << "Keyboard focus " << (view ? view->getName() : "(none)") << llendl;
02586 }
02587 
02588 class LLSelfStandUp : public view_listener_t
02589 {
02590         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02591         {
02592                 gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
02593                 return true;
02594         }
02595 };
02596 
02597 class LLSelfEnableStandUp : public view_listener_t
02598 {
02599         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02600         {
02601                 bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting;
02602                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
02603                 return true;
02604         }
02605 };
02606 
02607 BOOL check_admin_override(void*)
02608 {
02609         return gAgent.getAdminOverride();
02610 }
02611 
02612 void handle_admin_override_toggle(void*)
02613 {
02614         if(!gAgent.getAdminOverride())
02615         {
02616                 gAgent.setAdminOverride(TRUE);
02617                 show_debug_menus();
02618         }
02619         else gAgent.setAdminOverride(FALSE);
02620 }
02621 
02622 void handle_god_mode(void*)
02623 {
02624         gAgent.requestEnterGodMode();
02625 }
02626 
02627 void handle_leave_god_mode(void*)
02628 {
02629         gAgent.requestLeaveGodMode();
02630 }
02631 
02632 void set_god_level(U8 god_level)
02633 {
02634                 U8 old_god_level = gAgent.getGodLevel();
02635                 gAgent.setGodLevel( god_level );
02636                 show_debug_menus();
02637                 gIMMgr->refresh();
02638                 gParcelMgr->notifyObservers();
02639 
02640                 // Some classifieds change visibility on god mode
02641                 LLFloaterDirectory::requestClassifieds();
02642 
02643                 // God mode changes sim visibility
02644                 gWorldMap->reset();
02645                 gWorldMap->setCurrentLayer(0);
02646 
02647                 // inventory in items may change in god mode
02648                 gObjectList.dirtyAllObjectInventory();
02649 
02650                 LLString::format_map_t args;
02651                 if(god_level > GOD_NOT)
02652                 {
02653                         args["[LEVEL]"] = llformat("%d",(S32)god_level);
02654                         if (gInProductionGrid)
02655                         {
02656                                 gMenuBarView->setBackgroundColor( gColors.getColor( "MenuBarGodBgColor" ) );
02657                                 gStatusBar->setBackgroundColor( gColors.getColor( "MenuBarGodBgColor" ) );
02658                         }
02659                         else
02660                         {
02661                                 gMenuBarView->setBackgroundColor( gColors.getColor( "MenuNonProductionGodBgColor" ) );
02662                                 gStatusBar->setBackgroundColor( gColors.getColor( "MenuNonProductionGodBgColor" ) );
02663                         }
02664                         LLNotifyBox::showXml("EnteringGodMode", args);
02665                 }
02666                 else
02667                 {
02668                         args["[LEVEL]"] = llformat("%d",(S32)old_god_level);
02669                         if (gInProductionGrid)
02670                         {
02671                                 gMenuBarView->setBackgroundColor( gColors.getColor( "MenuBarBgColor" ) );
02672                                 gStatusBar->setBackgroundColor( gColors.getColor( "MenuBarBgColor" ) );
02673                         }
02674                         else
02675                         {
02676                                 gMenuBarView->setBackgroundColor( gColors.getColor( "MenuNonProductionBgColor" ) );
02677                                 gStatusBar->setBackgroundColor( gColors.getColor( "MenuNonProductionBgColor" ) );
02678                         }
02679                         LLNotifyBox::showXml("LeavingGodMode", args);
02680                 }
02681 }
02682 
02683 #ifdef TOGGLE_HACKED_GODLIKE_VIEWER
02684 void handle_toggle_hacked_godmode(void*)
02685 {
02686         gHackGodmode = !gHackGodmode;
02687         set_god_level(gHackGodmode ? GOD_MAINTENANCE : GOD_NOT);
02688 }
02689 
02690 BOOL check_toggle_hacked_godmode(void*)
02691 {
02692         return gHackGodmode;
02693 }
02694 #endif
02695 
02696 void process_grant_godlike_powers(LLMessageSystem* msg, void**)
02697 {
02698         LLUUID agent_id;
02699         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
02700         LLUUID session_id;
02701         msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
02702         if((agent_id == gAgent.getID()) && (session_id == gAgent.getSessionID()))
02703         {
02704                 U8 god_level;
02705                 msg->getU8Fast(_PREHASH_GrantData, _PREHASH_GodLevel, god_level);
02706                 set_god_level(god_level);
02707         }
02708         else
02709         {
02710                 llwarns << "Grant godlike for wrong agent " << agent_id << llendl;
02711         }
02712 }
02713 
02714 void load_url_local_file(const char* file_name)
02715 {
02716         if( gAgent.cameraMouselook() )
02717         {
02718                 gAgent.changeCameraToDefault();
02719         }
02720 
02721 #if LL_DARWIN || LL_LINUX || LL_SOLARIS
02722         // MBW -- If the Mac client is in fullscreen mode, it needs to go windowed so the browser will be visible.
02723         if(gViewerWindow->mWindow->getFullscreen())
02724         {
02725                 gViewerWindow->toggleFullscreen(TRUE);
02726         }
02727 #endif
02728 
02729         // JC - system() blocks until IE has launched.
02730         // spawn() runs asynchronously, but opens a command prompt.
02731         // ShellExecute() just opens the damn file with the default
02732         // web browser.
02733         std::string full_path = "file:///";
02734         full_path.append(gDirUtilp->getAppRODataDir());
02735         full_path.append(gDirUtilp->getDirDelimiter());
02736         full_path.append(file_name);
02737 
02738         LLWeb::loadURL(full_path.c_str());
02739 }
02740 
02741 /*
02742 class LLHaveCallingcard : public LLInventoryCollectFunctor
02743 {
02744 public:
02745         LLHaveCallingcard(const LLUUID& agent_id);
02746         virtual ~LLHaveCallingcard() {}
02747         virtual bool operator()(LLInventoryCategory* cat,
02748                                                         LLInventoryItem* item);
02749         BOOL isThere() const { return mIsThere;}
02750 protected:
02751         LLUUID mID;
02752         BOOL mIsThere;
02753 };
02754 
02755 LLHaveCallingcard::LLHaveCallingcard(const LLUUID& agent_id) :
02756         mID(agent_id),
02757         mIsThere(FALSE)
02758 {
02759 }
02760 
02761 bool LLHaveCallingcard::operator()(LLInventoryCategory* cat,
02762                                                                    LLInventoryItem* item)
02763 {
02764         if(item)
02765         {
02766                 if((item->getType() == LLAssetType::AT_CALLINGCARD)
02767                    && (item->getCreatorUUID() == mID))
02768                 {
02769                         mIsThere = TRUE;
02770                 }
02771         }
02772         return FALSE;
02773 }
02774 */
02775 
02776 BOOL is_agent_friend(const LLUUID& agent_id)
02777 {
02778         return (LLAvatarTracker::instance().getBuddyInfo(agent_id) != NULL);
02779 }
02780 
02781 BOOL is_agent_mappable(const LLUUID& agent_id)
02782 {
02783         return (is_agent_friend(agent_id) &&
02784                 LLAvatarTracker::instance().getBuddyInfo(agent_id)->isOnline() &&
02785                 LLAvatarTracker::instance().getBuddyInfo(agent_id)->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)
02786                 );
02787 }
02788 
02789 // Enable a menu item when you have someone's card.
02790 /*
02791 BOOL enable_have_card(void *userdata)
02792 {
02793         LLUUID* avatar_id = (LLUUID *)userdata;
02794         if (gAgent.isGodlike())
02795         {
02796                 return TRUE;
02797         }
02798         else if(avatar_id)
02799         {
02800                 return is_agent_friend(*avatar_id);
02801         }
02802         else
02803         {
02804                 return FALSE;
02805         }
02806 }
02807 */
02808 
02809 // Enable a menu item when you don't have someone's card.
02810 class LLAvatarEnableAddFriend : public view_listener_t
02811 {
02812         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02813         {
02814                 LLVOAvatar* avatar = find_avatar_from_object(gViewerWindow->lastObjectHit());
02815                 bool new_value = avatar && !is_agent_friend(avatar->getID());
02816                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
02817                 return true;
02818         }
02819 };
02820 
02821 void request_friendship(const LLUUID& dest_id)
02822 {
02823         LLViewerObject* dest = gObjectList.findObject(dest_id);
02824         if(dest && dest->isAvatar())
02825         {
02826                 LLString fullname;
02827                 LLString::format_map_t args;
02828                 LLNameValue* nvfirst = dest->getNVPair("FirstName");
02829                 LLNameValue* nvlast = dest->getNVPair("LastName");
02830                 if(nvfirst && nvlast)
02831                 {
02832                         args["[FIRST]"] = nvfirst->getString();
02833                         args["[LAST]"] = nvlast->getString();
02834                         fullname = nvfirst->getString();
02835                         fullname += " ";
02836                         fullname += nvlast->getString();
02837                 }
02838                 if (!fullname.empty())
02839                 {
02840                         LLPanelFriends::requestFriendship(dest_id, fullname);
02841                         LLNotifyBox::showXml("OfferedFriendship", args);
02842                 }
02843                 else
02844                 {
02845                         gViewerWindow->alertXml("CantOfferFriendship");
02846                 }
02847         }
02848 }
02849 
02850 
02851 class LLEditEnableCustomizeAvatar : public view_listener_t
02852 {
02853         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02854         {
02855                 bool new_value = gAgent.getWearablesLoaded();
02856                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
02857                 return true;
02858         }
02859 };
02860 
02861 bool handle_sit_or_stand()
02862 {
02863         LLViewerObject *object = gObjectList.findObject(gLastHitNonFloraObjectID);      
02864         if (!object)
02865         {
02866                 return true;
02867         }
02868 
02869         if (sitting_on_selection())
02870         {
02871                 gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
02872                 return true;
02873         }
02874 
02875         // get object selection offset 
02876 
02877         if (object && object->getPCode() == LL_PCODE_VOLUME)
02878         {
02879                 LLVector3d offset_double = gViewerWindow->lastNonFloraObjectHitOffset();
02880                 LLVector3 offset_single;
02881                 offset_single.setVec(offset_double);
02882                 
02883                 gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit);
02884                 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
02885                 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
02886                 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
02887                 gMessageSystem->nextBlockFast(_PREHASH_TargetObject);
02888                 gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID);
02889                 gMessageSystem->addVector3Fast(_PREHASH_Offset, offset_single);
02890 
02891                 object->getRegion()->sendReliableMessage();
02892         }
02893         return true;
02894 }
02895 
02896 class LLObjectSitOrStand : public view_listener_t
02897 {
02898         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02899         {
02900                 return handle_sit_or_stand();
02901         }
02902 };
02903 
02904 void near_sit_down_point(BOOL success, void *)
02905 {
02906         if (success)
02907         {
02908                 gAgent.setFlying(FALSE);
02909                 gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
02910 
02911                 // Might be first sit
02912                 LLFirstUse::useSit();
02913         }
02914 }
02915 
02916 class LLLandSit : public view_listener_t
02917 {
02918         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
02919         {
02920                 gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
02921                 gParcelMgr->deselectLand();
02922 
02923                 LLVector3d posGlobal = gLastHitPosGlobal;
02924                 
02925                 LLQuaternion target_rot;
02926                 if (gAgent.getAvatarObject())
02927                 {
02928                         target_rot = gAgent.getAvatarObject()->getRotation();
02929                 }
02930                 else
02931                 {
02932                         target_rot = gAgent.getFrameAgent().getQuaternion();
02933                 }
02934                 gAgent.startAutoPilotGlobal(posGlobal, "Sit", &target_rot, near_sit_down_point, NULL, 0.7f);
02935                 return true;
02936         }
02937 };
02938 
02939 void show_permissions_control(void*)
02940 {
02941         LLFloaterPermissionsMgr* floaterp = LLFloaterPermissionsMgr::show();
02942         floaterp->mPermissions->addPermissionsData("foo1", LLUUID::null, 0);
02943         floaterp->mPermissions->addPermissionsData("foo2", LLUUID::null, 0);
02944         floaterp->mPermissions->addPermissionsData("foo3", LLUUID::null, 0);
02945 }
02946 
02947 #if 0 // Unused (these just modify AudioInfoPage which is not used anywhere in the code
02948 void handle_audio_status_1(void*)
02949 {
02950         S32 page = gSavedSettings.getS32("AudioInfoPage");
02951         if (1 == page)
02952         {
02953                 page = 0;
02954         }
02955         else
02956         {
02957                 page = 1;
02958         }
02959         gSavedSettings.setS32("AudioInfoPage", page);   
02960 }
02961 
02962 void handle_audio_status_2(void*)
02963 {
02964         S32 page = gSavedSettings.getS32("AudioInfoPage");
02965         if (2 == page)
02966         {
02967                 page = 0;
02968         }
02969         else
02970         {
02971                 page = 2;
02972         }
02973         gSavedSettings.setS32("AudioInfoPage", page);   
02974 }
02975 
02976 void handle_audio_status_3(void*)
02977 {
02978         S32 page = gSavedSettings.getS32("AudioInfoPage");
02979         if (3 == page)
02980         {
02981                 page = 0;
02982         }
02983         else
02984         {
02985                 page = 3;
02986         }
02987         gSavedSettings.setS32("AudioInfoPage", page);   
02988 }
02989 
02990 void handle_audio_status_4(void*)
02991 {
02992         S32 page = gSavedSettings.getS32("AudioInfoPage");
02993         if (4 == page)
02994         {
02995                 page = 0;
02996         }
02997         else
02998         {
02999                 page = 4;
03000         }
03001         gSavedSettings.setS32("AudioInfoPage", page);   
03002 }
03003 #endif
03004 
03005 void manage_landmarks(void*)
03006 {
03007         LLFloaterLandmark::showInstance(1);
03008 }
03009 
03010 void create_new_landmark(void*)
03011 {
03012         // Note this is temporary cut and paste of legacy functionality.
03013         // TODO: Make this spawn a floater allowing user customize before creating the inventory object
03014 
03015         LLViewerRegion* agent_region = gAgent.getRegion();
03016         if(!agent_region)
03017         {
03018                 llwarns << "No agent region" << llendl;
03019                 return;
03020         }
03021         LLParcel* agent_parcel = gParcelMgr->getAgentParcel();
03022         if (!agent_parcel)
03023         {
03024                 llwarns << "No agent parcel" << llendl;
03025                 return;
03026         }
03027         if (!agent_parcel->getAllowLandmark()
03028                 && !LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
03029         {
03030                 gViewerWindow->alertXml("CannotCreateLandmarkNotOwner");
03031                 return;
03032         }
03033 
03034         LLUUID folder_id;
03035         folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
03036         std::string pos_string;
03037         gAgent.buildLocationString(pos_string);
03038 
03039         create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
03040                 folder_id, LLTransactionID::tnull,
03041                 pos_string, pos_string, // name, desc
03042                 LLAssetType::AT_LANDMARK,
03043                 LLInventoryType::IT_LANDMARK,
03044                 NOT_WEARABLE, PERM_ALL, 
03045                 NULL);
03046 }
03047 
03048 void landmark_menu_action(void* userdata)
03049 {
03050         LLUUID item_id = *(LLUUID*)userdata;
03051 
03052         LLViewerInventoryItem* itemp = gInventory.getItem(item_id);
03053         if (itemp)
03054         {
03055                 open_landmark(itemp, itemp->getName(), FALSE);
03056         }
03057 }
03058 
03059 void reload_ui(void *)
03060 {
03061         gUICtrlFactory->rebuild();
03062 }
03063 
03064 class LLWorldFly : public view_listener_t
03065 {
03066         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03067         {
03068                 gAgent.toggleFlying();
03069                 return true;
03070         }
03071 };
03072 
03073 void handle_agent_stop_moving(void*)
03074 {
03075         // stop agent
03076         gAgent.setControlFlags(AGENT_CONTROL_STOP);
03077 
03078         // cancel autopilot
03079         gAgent.stopAutoPilot();
03080 }
03081 
03082 void print_packets_lost(void*)
03083 {
03084         gWorldPointer->printPacketsLost();
03085 }
03086 
03087 
03088 void drop_packet(void*)
03089 {
03090         gMessageSystem->mPacketRing.dropPackets(1);
03091 }
03092 
03093 
03094 void velocity_interpolate( void* data )
03095 {
03096         BOOL toggle = gSavedSettings.getBOOL("VelocityInterpolate");
03097         LLMessageSystem* msg = gMessageSystem;
03098         if ( !toggle )
03099         {
03100                 msg->newMessageFast(_PREHASH_VelocityInterpolateOn);
03101                 msg->nextBlockFast(_PREHASH_AgentData);
03102                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03103                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03104                 gAgent.sendReliableMessage();
03105                 llinfos << "Velocity Interpolation On" << llendl;
03106         }
03107         else
03108         {
03109                 msg->newMessageFast(_PREHASH_VelocityInterpolateOff);
03110                 msg->nextBlockFast(_PREHASH_AgentData);
03111                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03112                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03113                 gAgent.sendReliableMessage();
03114                 llinfos << "Velocity Interpolation Off" << llendl;
03115         }
03116         // BUG this is a hack because of the change in menu behavior.  The
03117         // old menu system would automatically change a control's value,
03118         // but the new LLMenuGL system doesn't know what a control
03119         // is. However, it's easy to distinguish between the two callers
03120         // because LLMenuGL passes in the name of the user data (the
03121         // control name) to the callback function, and the user data goes
03122         // unused in the old menu code. Thus, if data is not null, then we
03123         // need to swap the value of the control.
03124         if( data )
03125         {
03126                 gSavedSettings.setBOOL( static_cast<char*>(data), !toggle );
03127         }
03128 }
03129 
03130 
03131 void update_fov(S32 increments)
03132 {
03133         F32 old_fov = gCamera->getDefaultFOV();
03134         // for each increment, FoV is 20% bigger
03135         F32 new_fov = old_fov * pow(1.2f, increments);
03136 
03137         // cap the FoV
03138         new_fov = llclamp(new_fov, MIN_FIELD_OF_VIEW, MAX_FIELD_OF_VIEW);
03139 
03140         if (new_fov != old_fov)
03141         {
03142                 LLMessageSystem* msg = gMessageSystem;
03143                 msg->newMessageFast(_PREHASH_AgentFOV);
03144                 msg->nextBlockFast(_PREHASH_AgentData);
03145                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03146                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03147                 msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
03148 
03149                 msg->nextBlockFast(_PREHASH_FOVBlock);
03150                 msg->addU32Fast(_PREHASH_GenCounter, 0);
03151                 msg->addF32Fast(_PREHASH_VerticalAngle, new_fov);
03152 
03153                 gAgent.sendReliableMessage();
03154 
03155                 // force agent to update dirty patches
03156                 gCamera->setDefaultFOV(new_fov);
03157                 gCamera->setView(new_fov);
03158         }
03159 }
03160 
03161 class LLViewZoomOut : public view_listener_t
03162 {
03163         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03164         {
03165                 update_fov(1);
03166                 return true;
03167         }
03168 };
03169 
03170 class LLViewZoomIn : public view_listener_t
03171 {
03172         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03173         {
03174                 update_fov(-1);
03175                 return true;
03176         }
03177 };
03178 
03179 class LLViewZoomDefault : public view_listener_t
03180 {
03181         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03182         {
03183                 F32 old_fov = gCamera->getView();
03184                 // for each increment, FoV is 20% bigger
03185                 F32 new_fov = DEFAULT_FIELD_OF_VIEW;
03186 
03187                 if (new_fov != old_fov)
03188                 {
03189                         LLMessageSystem* msg = gMessageSystem;
03190                         msg->newMessageFast(_PREHASH_AgentFOV);
03191                         msg->nextBlockFast(_PREHASH_AgentData);
03192                         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03193                         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03194                         msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
03195                         msg->nextBlockFast(_PREHASH_FOVBlock);
03196                         msg->addU32Fast(_PREHASH_GenCounter, 0);
03197                         msg->addF32Fast(_PREHASH_VerticalAngle, new_fov);
03198 
03199                         gAgent.sendReliableMessage();
03200 
03201                         // force agent to update dirty patches
03202                         gCamera->setDefaultFOV(new_fov);
03203                         gCamera->setView(new_fov);
03204                 }
03205                 return true;
03206         }
03207 };
03208 
03209 
03210 
03211 void toggle_wind_audio(void)
03212 {
03213         if (gAudiop)
03214         {
03215                 gAudiop->enableWind(!(gAudiop->isWindEnabled()));
03216         }
03217 }
03218 
03219 
03220 // Callback for enablement
03221 BOOL is_inventory_visible( void* user_data )
03222 {
03223         LLInventoryView* iv = reinterpret_cast<LLInventoryView*>(user_data);
03224         if( iv )
03225         {
03226                 return iv->getVisible();
03227         }
03228         return FALSE;
03229 }
03230 
03231 void handle_show_newest_map(void*)
03232 {
03233         LLFloaterWorldMap::show(NULL, FALSE);
03234 }
03235 
03236 //-------------------------------------------------------------------
03237 // Help menu functions
03238 //-------------------------------------------------------------------
03239 
03240 class LLHelpMOTD : public view_listener_t
03241 {
03242         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03243         {
03244                 LLString::format_map_t args;
03245                 args["[MOTD]"] = gAgent.mMOTD;
03246                 gViewerWindow->alertXml("MOTD", args, NULL, NULL);
03247                 return true;
03248         }
03249 };
03250 
03251 //
03252 // Major mode switching
03253 //
03254 void reset_view_final( BOOL proceed, void* );
03255 
03256 void handle_reset_view()
03257 {
03258         if( (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode()) && gFloaterCustomize )
03259         {
03260                 // Show dialog box if needed.
03261                 gFloaterCustomize->askToSaveAllIfDirty( reset_view_final, NULL );
03262         }
03263         else
03264         {
03265                 reset_view_final( TRUE, NULL );
03266         }
03267 }
03268 
03269 class LLViewResetView : public view_listener_t
03270 {
03271         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03272         {
03273                 handle_reset_view();
03274                 return true;
03275         }
03276 };
03277 
03278 // Note: extra parameters allow this function to be called from dialog.
03279 void reset_view_final( BOOL proceed, void* ) 
03280 {
03281         if( !proceed )
03282         {
03283                 return;
03284         }
03285 
03286         gAgent.changeCameraToDefault();
03287         
03288         if (LLViewerJoystick::sOverrideCamera)
03289         {
03290                 handle_toggle_flycam(NULL);
03291         }
03292 
03293         gAgent.resetView(!gFloaterTools->getVisible());
03294         gFloaterTools->close();
03295         
03296         gViewerWindow->showCursor();
03297 
03298         // Switch back to basic toolset
03299         gToolMgr->setCurrentToolset(gBasicToolset);
03300 }
03301 
03302 class LLViewLookAtLastChatter : public view_listener_t
03303 {
03304         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03305         {
03306                 gAgent.lookAtLastChat();
03307                 return true;
03308         }
03309 };
03310 
03311 class LLViewMouselook : public view_listener_t
03312 {
03313         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03314         {
03315                 if (!gAgent.cameraMouselook())
03316                 {
03317                         gAgent.changeCameraToMouselook();
03318                 }
03319                 else
03320                 {
03321                         gAgent.changeCameraToDefault();
03322                 }
03323                 return true;
03324         }
03325 };
03326 
03327 class LLViewFullscreen : public view_listener_t
03328 {
03329         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03330         {
03331                 gViewerWindow->toggleFullscreen(TRUE);
03332                 return true;
03333         }
03334 };
03335 
03336 class LLViewDefaultUISize : public view_listener_t
03337 {
03338         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03339         {
03340                 gSavedSettings.setF32("UIScaleFactor", 1.0f);
03341                 gSavedSettings.setBOOL("UIAutoScale", FALSE);   
03342                 gViewerWindow->reshape(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight());
03343                 return true;
03344         }
03345 };
03346 
03347 class LLEditDuplicate : public view_listener_t
03348 {
03349         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03350         {
03351                 if(gEditMenuHandler)
03352                 {
03353                         gEditMenuHandler->duplicate();
03354                 }
03355                 return true;
03356         }
03357 };
03358 
03359 class LLEditEnableDuplicate : public view_listener_t
03360 {
03361         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03362         {
03363                 bool new_value = gEditMenuHandler && gEditMenuHandler->canDuplicate();
03364                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
03365                 return true;
03366         }
03367 };
03368 
03369 
03370 void disabled_duplicate(void*)
03371 {
03372         if (gSelectMgr->getSelection()->getFirstObject())
03373         {
03374                 LLNotifyBox::showXml("CopyFailed");
03375         }
03376 }
03377 
03378 void handle_duplicate_in_place(void*)
03379 {
03380         llinfos << "handle_duplicate_in_place" << llendl;
03381 
03382         LLVector3 offset(0.f, 0.f, 0.f);
03383         gSelectMgr->selectDuplicate(offset, TRUE);
03384 }
03385 
03386 void handle_repeat_duplicate(void*)
03387 {
03388         gSelectMgr->repeatDuplicate();
03389 }
03390 
03391 void handle_deed_object_to_group(void*)
03392 {
03393         LLUUID group_id;
03394         
03395         gSelectMgr->selectGetGroup(group_id);
03396         gSelectMgr->sendOwner(LLUUID::null, group_id, FALSE);
03397         gViewerStats->incStat(LLViewerStats::ST_RELEASE_COUNT);
03398 }
03399 
03400 BOOL enable_deed_object_to_group(void*)
03401 {
03402         if(gSelectMgr->getSelection()->isEmpty()) return FALSE;
03403         LLPermissions perm;
03404         LLUUID group_id;
03405 
03406         if (gSelectMgr->selectGetGroup(group_id) &&
03407                 gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) &&
03408                 gSelectMgr->selectGetPermissions(perm) &&
03409                 perm.deedToGroup(gAgent.getID(), group_id))
03410         {
03411                 return TRUE;
03412         }
03413         return FALSE;
03414 }
03415 
03416 
03417 /*
03418  * No longer able to support viewer side manipulations in this way
03419  *
03420 void god_force_inv_owner_permissive(LLViewerObject* object,
03421                                                                         InventoryObjectList* inventory,
03422                                                                         S32 serial_num,
03423                                                                         void*)
03424 {
03425         typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t;
03426         item_array_t items;
03427 
03428         InventoryObjectList::const_iterator inv_it = inventory->begin();
03429         InventoryObjectList::const_iterator inv_end = inventory->end();
03430         for ( ; inv_it != inv_end; ++inv_it)
03431         {
03432                 if(((*inv_it)->getType() != LLAssetType::AT_CATEGORY)
03433                    && ((*inv_it)->getType() != LLAssetType::AT_ROOT_CATEGORY))
03434                 {
03435                         LLInventoryObject* obj = *inv_it;
03436                         LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem((LLViewerInventoryItem*)obj);
03437                         LLPermissions perm(new_item->getPermissions());
03438                         perm.setMaskBase(PERM_ALL);
03439                         perm.setMaskOwner(PERM_ALL);
03440                         new_item->setPermissions(perm);
03441                         items.push_back(new_item);
03442                 }
03443         }
03444         item_array_t::iterator end = items.end();
03445         item_array_t::iterator it;
03446         for(it = items.begin(); it != end; ++it)
03447         {
03448                 // since we have the inventory item in the callback, it should not
03449                 // invalidate iteration through the selection manager.
03450                 object->updateInventory((*it), TASK_INVENTORY_ITEM_KEY, false);
03451         }
03452 }
03453 */
03454 
03455 void handle_object_owner_permissive(void*)
03456 {
03457         // only send this if they're a god.
03458         if(gAgent.isGodlike())
03459         {
03460                 // do the objects.
03461                 gSelectMgr->selectionSetObjectPermissions(PERM_BASE, TRUE, PERM_ALL, TRUE);
03462                 gSelectMgr->selectionSetObjectPermissions(PERM_OWNER, TRUE, PERM_ALL, TRUE);
03463         }
03464 }
03465 
03466 void handle_object_owner_self(void*)
03467 {
03468         // only send this if they're a god.
03469         if(gAgent.isGodlike())
03470         {
03471                 gSelectMgr->sendOwner(gAgent.getID(), gAgent.getGroupID(), TRUE);
03472         }
03473 }
03474 
03475 // Shortcut to set owner permissions to not editable.
03476 void handle_object_lock(void*)
03477 {
03478         gSelectMgr->selectionSetObjectPermissions(PERM_OWNER, FALSE, PERM_MODIFY);
03479 }
03480 
03481 void handle_object_asset_ids(void*)
03482 {
03483         // only send this if they're a god.
03484         if (gAgent.isGodlike())
03485         {
03486                 gSelectMgr->sendGodlikeRequest("objectinfo", "assetids");
03487         }
03488 }
03489 
03490 void handle_force_parcel_owner_to_me(void*)
03491 {
03492         gParcelMgr->sendParcelGodForceOwner( gAgent.getID() );
03493 }
03494 
03495 void handle_force_parcel_to_content(void*)
03496 {
03497         gParcelMgr->sendParcelGodForceToContent();
03498 }
03499 
03500 void handle_claim_public_land(void*)
03501 {
03502         if (gParcelMgr->getSelectionRegion() != gAgent.getRegion())
03503         {
03504                 LLNotifyBox::showXml("ClaimPublicLand");
03505                 return;
03506         }
03507 
03508         LLVector3d west_south_global;
03509         LLVector3d east_north_global;
03510         gParcelMgr->getSelection(west_south_global, east_north_global);
03511         LLVector3 west_south = gAgent.getPosAgentFromGlobal(west_south_global);
03512         LLVector3 east_north = gAgent.getPosAgentFromGlobal(east_north_global);
03513 
03514         LLMessageSystem* msg = gMessageSystem;
03515         msg->newMessage("GodlikeMessage");
03516         msg->nextBlock("AgentData");
03517         msg->addUUID("AgentID", gAgent.getID());
03518         msg->addUUID("SessionID", gAgent.getSessionID());
03519         msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
03520         msg->nextBlock("MethodData");
03521         msg->addString("Method", "claimpublicland");
03522         msg->addUUID("Invoice", LLUUID::null);
03523         char buffer[32];                /* Flawfinder: ignore */
03524         snprintf(buffer, sizeof(buffer), "%f", west_south.mV[VX]);              /* Flawfinder: ignore */
03525         msg->nextBlock("ParamList");
03526         msg->addString("Parameter", buffer);
03527         snprintf(buffer, sizeof(buffer), "%f", west_south.mV[VY]);              /* Flawfinder: ignore */
03528         msg->nextBlock("ParamList");
03529         msg->addString("Parameter", buffer);
03530         snprintf(buffer, sizeof(buffer), "%f", east_north.mV[VX]);              /* Flawfinder: ignore */
03531         msg->nextBlock("ParamList");
03532         msg->addString("Parameter", buffer);
03533         snprintf(buffer, sizeof(buffer), "%f", east_north.mV[VY]);              /* Flawfinder: ignore */
03534         msg->nextBlock("ParamList");
03535         msg->addString("Parameter", buffer);
03536         gAgent.sendReliableMessage();
03537 }
03538 
03539 void handle_god_request_havok(void *)
03540 {
03541         if (gAgent.isGodlike())
03542         {
03543                 gSelectMgr->sendGodlikeRequest("havok", "infoverbose");
03544         }
03545 }
03546 
03547 //void handle_god_request_foo(void *)
03548 //{
03549 //      if (gAgent.isGodlike())
03550 //      {
03551 //              gSelectMgr->sendGodlikeRequest(GOD_WANTS_FOO);
03552 //      }
03553 //}
03554 
03555 //void handle_god_request_terrain_save(void *)
03556 //{
03557 //      if (gAgent.isGodlike())
03558 //      {
03559 //              gSelectMgr->sendGodlikeRequest("terrain", "save");
03560 //      }
03561 //}
03562 
03563 //void handle_god_request_terrain_load(void *)
03564 //{
03565 //      if (gAgent.isGodlike())
03566 //      {
03567 //              gSelectMgr->sendGodlikeRequest("terrain", "load");
03568 //      }
03569 //}
03570 
03571 
03572 // HACK for easily testing new avatar geometry
03573 void handle_god_request_avatar_geometry(void *)
03574 {
03575         if (gAgent.isGodlike())
03576         {
03577                 gSelectMgr->sendGodlikeRequest("avatar toggle", NULL);
03578         }
03579 }
03580 
03581 
03582 void handle_show_overlay_title(void*)
03583 {
03584         gShowOverlayTitle = !gShowOverlayTitle;
03585         gSavedSettings.setBOOL("ShowOverlayTitle", gShowOverlayTitle);
03586 }
03587 
03588 void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
03589 {
03590         if(gAgent.cameraMouselook())
03591         {
03592                 gAgent.changeCameraToDefault();
03593         }
03594         //gInventoryView->setPanelOpen(TRUE);
03595 
03596         std::string error;
03597         LLDynamicArray<LLViewerObject*> derez_objects;
03598         
03599         // Check conditions that we can't deal with, building a list of
03600         // everything that we'll actually be derezzing.
03601         LLViewerRegion* first_region = NULL;
03602         for (LLObjectSelection::valid_root_iterator iter = gSelectMgr->getSelection()->valid_root_begin();
03603                  iter != gSelectMgr->getSelection()->valid_root_end(); iter++)
03604         {
03605                 LLSelectNode* node = *iter;
03606                 LLViewerObject* object = node->getObject();
03607                 LLViewerRegion* region = object->getRegion();
03608                 if (!first_region)
03609                 {
03610                         first_region = region;
03611                 }
03612                 else
03613                 {
03614                         if(region != first_region)
03615                         {
03616                                 // Derez doesn't work at all if the some of the objects
03617                                 // are in regions besides the first object selected.
03618                                 
03619                                 // ...crosses region boundaries
03620                                 error = "AcquireErrorObjectSpan";
03621                                 break;
03622                         }
03623                 }
03624                 if (object->isAvatar())
03625                 {
03626                         // ...don't acquire avatars
03627                         continue;
03628                 }
03629 
03630                 // If AssetContainers are being sent back, they will appear as 
03631                 // boxes in the owner's inventory.
03632                 if (object->getNVPair("AssetContainer")
03633                         && dest != DRD_RETURN_TO_OWNER)
03634                 {
03635                         // this object is an asset container, derez its contents, not it
03636                         llwarns << "Attempt to derez deprecated AssetContainer object type not supported." << llendl;
03637                         /*
03638                         object->requestInventory(container_inventory_arrived, 
03639                                 (void *)(BOOL)(DRD_TAKE_INTO_AGENT_INVENTORY == dest));
03640                         */
03641                         continue;
03642                 }
03643                 BOOL can_derez_current = FALSE;
03644                 switch(dest)
03645                 {
03646                 case DRD_TAKE_INTO_AGENT_INVENTORY:
03647                 case DRD_TRASH:
03648                         if( (node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify())
03649                                 || (node->allowOperationOnNode(PERM_OWNER, GP_OBJECT_MANIPULATE)) )
03650                         {
03651                                 can_derez_current = TRUE;
03652                         }
03653                         break;
03654 
03655                 case DRD_RETURN_TO_OWNER:
03656                         can_derez_current = TRUE;
03657                         break;
03658 
03659                 default:
03660                         if((node->mPermissions->allowTransferTo(gAgent.getID())
03661                                 && object->permCopy())
03662                            || gAgent.isGodlike())
03663                         {
03664                                 can_derez_current = TRUE;
03665                         }
03666                         break;
03667                 }
03668                 if(can_derez_current)
03669                 {
03670                         derez_objects.put(object);
03671                 }
03672         }
03673 
03674         // This constant is based on (1200 - HEADER_SIZE) / 4 bytes per
03675         // root.  I lopped off a few (33) to provide a bit
03676         // pad. HEADER_SIZE is currently 67 bytes, most of which is UUIDs.
03677         // This gives us a maximum of 63500 root objects - which should
03678         // satisfy anybody.
03679         const S32 MAX_ROOTS_PER_PACKET = 250;
03680         const S32 MAX_PACKET_COUNT = 254;
03681         F32 packets = ceil((F32)derez_objects.count() / (F32)MAX_ROOTS_PER_PACKET);
03682         if(packets > (F32)MAX_PACKET_COUNT)
03683         {
03684                 error = "AcquireErrorTooManyObjects";
03685         }
03686 
03687         if(error.empty() && derez_objects.count() > 0)
03688         {
03689                 U8 d = (U8)dest;
03690                 LLUUID tid;
03691                 tid.generate();
03692                 U8 packet_count = (U8)packets;
03693                 S32 object_index = 0;
03694                 S32 objects_in_packet = 0;
03695                 LLMessageSystem* msg = gMessageSystem;
03696                 for(U8 packet_number = 0;
03697                         packet_number < packet_count;
03698                         ++packet_number)
03699                 {
03700                         msg->newMessageFast(_PREHASH_DeRezObject);
03701                         msg->nextBlockFast(_PREHASH_AgentData);
03702                         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
03703                         msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
03704                         msg->nextBlockFast(_PREHASH_AgentBlock);
03705                         msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
03706                         msg->addU8Fast(_PREHASH_Destination, d);        
03707                         msg->addUUIDFast(_PREHASH_DestinationID, dest_id);
03708                         msg->addUUIDFast(_PREHASH_TransactionID, tid);
03709                         msg->addU8Fast(_PREHASH_PacketCount, packet_count);
03710                         msg->addU8Fast(_PREHASH_PacketNumber, packet_number);
03711                         objects_in_packet = 0;
03712                         while((object_index < derez_objects.count())
03713                                   && (objects_in_packet++ < MAX_ROOTS_PER_PACKET))
03714 
03715                         {
03716                                 LLViewerObject* object = derez_objects.get(object_index++);
03717                                 msg->nextBlockFast(_PREHASH_ObjectData);
03718                                 msg->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
03719                                 // VEFFECT: DerezObject
03720                                 LLHUDEffectSpiral* effectp = (LLHUDEffectSpiral*)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
03721                                 effectp->setPositionGlobal(object->getPositionGlobal());
03722                                 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
03723                         }
03724                         msg->sendReliable(first_region->getHost());
03725                 }
03726                 make_ui_sound("UISndObjectRezOut");
03727 
03728                 // Busy count decremented by inventory update, so only increment
03729                 // if will be causing an update.
03730                 if (dest != DRD_RETURN_TO_OWNER)
03731                 {
03732                         gViewerWindow->getWindow()->incBusyCount();
03733                 }
03734         }
03735         else if(!error.empty())
03736         {
03737                 gViewerWindow->alertXml(error);
03738         }
03739 }
03740 
03741 class LLToolsTakeCopy : public view_listener_t
03742 {
03743         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03744         {
03745                 if (gSelectMgr->getSelection()->isEmpty()) return true;
03746 
03747                 const LLUUID& category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT);
03748                 derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id);
03749 
03750                 return true;
03751         }
03752 };
03753 
03754 
03755 // You can return an object to its owner if it is on your land.
03756 class LLObjectReturn : public view_listener_t
03757 {
03758         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03759         {
03760                 if (gSelectMgr->getSelection()->isEmpty()) return true;
03761                 
03762                 mObjectSelection = gSelectMgr->getEditSelection();
03763 
03764                 gViewerWindow->alertXml("ReturnToOwner",
03765                         onReturnToOwner,
03766                         (void*)this);
03767                 return true;
03768         }
03769 
03770         static void onReturnToOwner(S32 option, void* data)
03771         {
03772                 LLObjectReturn* object_return = (LLObjectReturn*)data;
03773 
03774                 if (0 == option)
03775                 {
03776                         // Ignore category ID for this derez destination.
03777                         derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null);
03778                 }
03779 
03780                 // drop reference to current selection
03781                 object_return->mObjectSelection = NULL;
03782         }
03783 
03784 protected:
03785         LLObjectSelectionHandle mObjectSelection;
03786 };
03787 
03788 
03789 // Allow return to owner if one or more of the selected items is
03790 // over land you own.
03791 class LLObjectEnableReturn : public view_listener_t
03792 {
03793         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
03794         {
03795 #ifdef HACKED_GODLIKE_VIEWER
03796                 bool new_value = true;
03797 #else
03798                 bool new_value = false;
03799                 if (gAgent.isGodlike())
03800                 {
03801                         new_value = true;
03802                 }
03803                 else
03804                 {
03805                         LLViewerRegion* region = gAgent.getRegion();
03806                         if (region)
03807                         {
03808                                 // Estate owners and managers can always return objects.
03809                                 if (region->canManageEstate())
03810                                 {
03811                                         new_value = true;
03812                                 }
03813                                 else
03814                                 {
03815                                         struct f : public LLSelectedObjectFunctor
03816                                         {
03817                                                 virtual bool apply(LLViewerObject* obj)
03818                                                 {
03819                                                         return (obj->isOverAgentOwnedLand() ||
03820                                                                         obj->isOverGroupOwnedLand() ||
03821                                                                         obj->permModify());
03822                                                 }
03823                                         } func;
03824                                         const bool firstonly = true;
03825                                         new_value = gSelectMgr->getSelection()->applyToRootObjects(&func, firstonly);
03826                                 }
03827                         }
03828                 }
03829 #endif
03830                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
03831                 return true;
03832         }
03833 };
03834 
03835 void force_take_copy(void*)
03836 {
03837         if (gSelectMgr->getSelection()->isEmpty()) return;
03838         const LLUUID& category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT);
03839         derez_objects(DRD_FORCE_TO_GOD_INVENTORY, category_id);
03840 }
03841 
03842 void handle_take()
03843 {
03844         // we want to use the folder this was derezzed from if it's
03845         // available. Otherwise, derez to the normal place.
03846         if(gSelectMgr->getSelection()->isEmpty())
03847         {
03848                 return;
03849         }
03850         
03851         BOOL you_own_everything = TRUE;
03852         BOOL locked_but_takeable_object = FALSE;
03853         LLUUID category_id;
03854         
03855         for (LLObjectSelection::root_iterator iter = gSelectMgr->getSelection()->root_begin();
03856                  iter != gSelectMgr->getSelection()->root_end(); iter++)
03857         {
03858                 LLSelectNode* node = *iter;
03859                 LLViewerObject* object = node->getObject();
03860                 if(object)
03861                 {
03862                         if(!object->permYouOwner())
03863                         {
03864                                 you_own_everything = FALSE;
03865                         }
03866 
03867                         if(!object->permMove())
03868                         {
03869                                 locked_but_takeable_object = TRUE;
03870                         }
03871                 }
03872                 if(node->mFolderID.notNull())
03873                 {
03874                         if(category_id.isNull())
03875                         {
03876                                 category_id = node->mFolderID;
03877                         }
03878                         else if(category_id != node->mFolderID)
03879                         {
03880                                 // we have found two potential destinations. break out
03881                                 // now and send to the default location.
03882                                 category_id.setNull();
03883                                 break;
03884                         }
03885                 }
03886         }
03887         if(category_id.notNull())
03888         {
03889                 // there is an unambiguous destination. See if this agent has
03890                 // such a location and it is not in the trash or library
03891                 if(!gInventory.getCategory(category_id))
03892                 {
03893                         // nope, set to NULL.
03894                         category_id.setNull();
03895                 }
03896                 if(category_id.notNull())
03897                 {
03898                         // check trash
03899                         LLUUID trash;
03900                         trash = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
03901                         if(category_id == trash || gInventory.isObjectDescendentOf(category_id, trash))
03902                         {
03903                                 category_id.setNull();
03904                         }
03905 
03906                         // check library
03907                         if(gInventory.isObjectDescendentOf(category_id, gInventoryLibraryRoot))
03908                         {
03909                                 category_id.setNull();
03910                         }
03911 
03912                 }
03913         }
03914         if(category_id.isNull())
03915         {
03916                 category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT);
03917         }
03918         LLUUID* cat_id = new LLUUID(category_id);
03919         if(locked_but_takeable_object ||
03920            !you_own_everything)
03921         {
03922                 if(locked_but_takeable_object && you_own_everything)
03923                 {
03924                         gViewerWindow->alertXml("ConfirmObjectTakeLock",
03925                         confirm_take,
03926                         (void*)cat_id);
03927 
03928                 }
03929                 else if(!locked_but_takeable_object && !you_own_everything)
03930                 {
03931                         gViewerWindow->alertXml("ConfirmObjectTakeNoOwn",
03932                         confirm_take,
03933                         (void*)cat_id);
03934                 }
03935                 else
03936                 {
03937                         gViewerWindow->alertXml("ConfirmObjectTakeLockNoOwn",
03938                         confirm_take,
03939                         (void*)cat_id);
03940                 }
03941 
03942 
03943         }
03944 
03945         else
03946         {
03947                 confirm_take(0, (void*)cat_id);
03948         }
03949 }
03950 
03951 void confirm_take(S32 option, void* data)
03952 {
03953         LLUUID* cat_id = (LLUUID*)data;
03954         if(!cat_id) return;
03955         if(enable_take() && (option == 0))
03956         {
03957                 derez_objects(DRD_TAKE_INTO_AGENT_INVENTORY, *cat_id);
03958         }
03959         delete cat_id;
03960 }
03961 
03962 // You can take an item when it is public and transferrable, or when
03963 // you own it. We err on the side of enabling the item when at least
03964 // one item selected can be copied to inventory.
03965 BOOL enable_take()
03966 {
03967         if (sitting_on_selection())
03968         {
03969                 return FALSE;
03970         }
03971 
03972         for (LLObjectSelection::valid_root_iterator iter = gSelectMgr->getSelection()->valid_root_begin();
03973                  iter != gSelectMgr->getSelection()->valid_root_end(); iter++)
03974         {
03975                 LLSelectNode* node = *iter;
03976                 LLViewerObject* object = node->getObject();
03977                 if (object->isAvatar())
03978                 {
03979                         // ...don't acquire avatars
03980                         continue;
03981                 }
03982 
03983 #ifdef HACKED_GODLIKE_VIEWER
03984                 return TRUE;
03985 #else
03986 # ifdef TOGGLE_HACKED_GODLIKE_VIEWER
03987                 if (!gInProductionGrid && gAgent.isGodlike())
03988                 {
03989                         return TRUE;
03990                 }
03991 # endif
03992                 if((node->mPermissions->allowTransferTo(gAgent.getID())
03993                         && object->permModify())
03994                    || (node->mPermissions->getOwner() == gAgent.getID()))
03995                 {
03996                         return TRUE;
03997                 }
03998 #endif
03999         }
04000         return FALSE;
04001 }
04002 
04003 class LLToolsBuyOrTake : public view_listener_t
04004 {
04005         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04006         {
04007                 if (gSelectMgr->getSelection()->isEmpty())
04008                 {
04009                         return true;
04010                 }
04011 
04012                 if (is_selection_buy_not_take())
04013                 {
04014                         S32 total_price = selection_price();
04015 
04016                         if (total_price <= gStatusBar->getBalance() || total_price == 0)
04017                         {
04018                                 handle_buy(NULL);
04019                         }
04020                         else
04021                         {
04022                                 LLFloaterBuyCurrency::buyCurrency(
04023                                         "Buying this costs", total_price);
04024                         }
04025                 }
04026                 else
04027                 {
04028                         handle_take();
04029                 }
04030                 return true;
04031         }
04032 };
04033 
04034 class LLToolsEnableBuyOrTake : public view_listener_t
04035 {
04036         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04037         {
04038                 bool is_buy = is_selection_buy_not_take();
04039                 bool new_value = is_buy ? enable_buy(NULL) : enable_take();
04040                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04041 
04042                 // Update label
04043                 LLString label;
04044                 LLString buy_text;
04045                 LLString take_text;
04046                 LLString param = userdata["data"].asString();
04047                 LLString::size_type offset = param.find(",");
04048                 if (offset != param.npos)
04049                 {
04050                         buy_text = param.substr(0, offset);
04051                         take_text = param.substr(offset+1);
04052                 }
04053                 if (is_buy)
04054                 {
04055                         label = buy_text;
04056                 }
04057                 else
04058                 {
04059                         label = take_text;
04060                 }
04061                 gMenuHolder->childSetText("Pie Object Take", label);
04062                 gMenuHolder->childSetText("Menu Object Take", label);
04063 
04064                 return true;
04065         }
04066 };
04067 
04068 // This is a small helper function to determine if we have a buy or a
04069 // take in the selection. This method is to help with the aliasing
04070 // problems of putting buy and take in the same pie menu space. After
04071 // a fair amont of discussion, it was determined to prefer buy over
04072 // take. The reasoning follows from the fact that when users walk up
04073 // to buy something, they will click on one or more items. Thus, if
04074 // anything is for sale, it becomes a buy operation, and the server
04075 // will group all of the buy items, and copyable/modifiable items into
04076 // one package and give the end user as much as the permissions will
04077 // allow. If the user wanted to take something, they will select fewer
04078 // and fewer items until only 'takeable' items are left. The one
04079 // exception is if you own everything in the selection that is for
04080 // sale, in this case, you can't buy stuff from yourself, so you can
04081 // take it.
04082 // return value = TRUE if selection is a 'buy'.
04083 //                FALSE if selection is a 'take'
04084 BOOL is_selection_buy_not_take()
04085 {
04086         for (LLObjectSelection::root_iterator iter = gSelectMgr->getSelection()->root_begin();
04087                  iter != gSelectMgr->getSelection()->root_end(); iter++)
04088         {
04089                 LLSelectNode* node = *iter;
04090                 LLViewerObject* obj = node->getObject();
04091                 if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale()))
04092                 {
04093                         // you do not own the object and it is for sale, thus,
04094                         // it's a buy
04095                         return TRUE;
04096                 }
04097         }
04098         return FALSE;
04099 }
04100 
04101 S32 selection_price()
04102 {
04103         S32 total_price = 0;
04104         for (LLObjectSelection::root_iterator iter = gSelectMgr->getSelection()->root_begin();
04105                  iter != gSelectMgr->getSelection()->root_end(); iter++)
04106         {
04107                 LLSelectNode* node = *iter;
04108                 LLViewerObject* obj = node->getObject();
04109                 if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale()))
04110                 {
04111                         // you do not own the object and it is for sale.
04112                         // Add its price.
04113                         total_price += node->mSaleInfo.getSalePrice();
04114                 }
04115         }
04116 
04117         return total_price;
04118 }
04119 
04120 void callback_show_buy_currency(S32 option, void*)
04121 {
04122         if (0 == option)
04123         {
04124                 llinfos << "Loading page " << BUY_CURRENCY_URL << llendl;
04125                 LLWeb::loadURL(BUY_CURRENCY_URL);
04126         }
04127 }
04128 
04129 
04130 void show_buy_currency(const char* extra)
04131 {
04132         // Don't show currency web page for branded clients.
04133 
04134         std::ostringstream mesg;
04135         if (extra != NULL)
04136         {       
04137                 mesg << extra << "\n \n";
04138         }
04139         mesg << "Go to " << BUY_CURRENCY_URL << "\nfor information on purchasing currency?";
04140 
04141         LLString::format_map_t args;
04142         if (extra != NULL)
04143         {
04144                 args["[EXTRA]"] = extra;
04145         }
04146         args["[URL]"] = BUY_CURRENCY_URL;
04147         gViewerWindow->alertXml("PromptGoToCurrencyPage", args, 
04148                 callback_show_buy_currency);
04149 }
04150 
04151 void handle_buy_currency(void*)
04152 {
04153 //      LLFloaterBuyCurrency::buyCurrency();
04154 }
04155 
04156 void handle_buy(void*)
04157 {
04158         if (gSelectMgr->getSelection()->isEmpty()) return;
04159 
04160         LLSaleInfo sale_info;
04161         BOOL valid = gSelectMgr->selectGetSaleInfo(sale_info);
04162         if (!valid) return;
04163 
04164         if (sale_info.getSaleType() == LLSaleInfo::FS_CONTENTS)
04165         {
04166                 handle_buy_contents(sale_info);
04167         }
04168         else
04169         {
04170                 handle_buy_object(sale_info);
04171         }
04172 }
04173 
04174 class LLObjectBuy : public view_listener_t
04175 {
04176         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04177         {
04178                 handle_buy(NULL);
04179                 return true;
04180         }
04181 };
04182 
04183 BOOL sitting_on_selection()
04184 {
04185         LLSelectNode* node = gSelectMgr->getSelection()->getFirstRootNode();
04186         if (!node)
04187         {
04188                 return FALSE;
04189         }
04190 
04191         if (!node->mValid)
04192         {
04193                 return FALSE;
04194         }
04195 
04196         LLViewerObject* root_object = node->getObject();
04197         if (!root_object)
04198         {
04199                 return FALSE;
04200         }
04201 
04202         // Need to determine if avatar is sitting on this object
04203         LLVOAvatar* avatar = gAgent.getAvatarObject();
04204         if (!avatar)
04205         {
04206                 return FALSE;
04207         }
04208 
04209         return (avatar->mIsSitting && avatar->getRoot() == root_object);
04210 }
04211 
04212 class LLToolsSaveToInventory : public view_listener_t
04213 {
04214         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04215         {
04216                 if(enable_save_into_inventory(NULL))
04217                 {
04218                         derez_objects(DRD_SAVE_INTO_AGENT_INVENTORY, LLUUID::null);
04219                 }
04220                 return true;
04221         }
04222 };
04223 
04224 class LLToolsSaveToObjectInventory : public view_listener_t
04225 {
04226         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04227         {
04228                 if(gSelectMgr)
04229                 {
04230                         LLSelectNode* node = gSelectMgr->getSelection()->getFirstRootNode();
04231                         if(node && (node->mValid) && (!node->mFromTaskID.isNull()))
04232                         {
04233                                 // *TODO: check to see if the fromtaskid object exists.
04234                                 derez_objects(DRD_SAVE_INTO_TASK_INVENTORY, node->mFromTaskID);
04235                         }
04236                 }
04237                 return true;
04238         }
04239 };
04240 
04241 // Round the position of all root objects to the grid
04242 class LLToolsSnapObjectXY : public view_listener_t
04243 {
04244         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04245         {
04246                 F64 snap_size = (F64)gSavedSettings.getF32("GridResolution");
04247 
04248                 for (LLObjectSelection::root_iterator iter = gSelectMgr->getSelection()->root_begin();
04249                          iter != gSelectMgr->getSelection()->root_end(); iter++)
04250                 {
04251                         LLSelectNode* node = *iter;
04252                         LLViewerObject* obj = node->getObject();
04253                         if (obj->permModify())
04254                         {
04255                                 LLVector3d pos_global = obj->getPositionGlobal();
04256                                 F64 round_x = fmod(pos_global.mdV[VX], snap_size);
04257                                 if (round_x < snap_size * 0.5)
04258                                 {
04259                                         // closer to round down
04260                                         pos_global.mdV[VX] -= round_x;
04261                                 }
04262                                 else
04263                                 {
04264                                         // closer to round up
04265                                         pos_global.mdV[VX] -= round_x;
04266                                         pos_global.mdV[VX] += snap_size;
04267                                 }
04268 
04269                                 F64 round_y = fmod(pos_global.mdV[VY], snap_size);
04270                                 if (round_y < snap_size * 0.5)
04271                                 {
04272                                         pos_global.mdV[VY] -= round_y;
04273                                 }
04274                                 else
04275                                 {
04276                                         pos_global.mdV[VY] -= round_y;
04277                                         pos_global.mdV[VY] += snap_size;
04278                                 }
04279 
04280                                 obj->setPositionGlobal(pos_global, FALSE);
04281                         }
04282                 }
04283                 gSelectMgr->sendMultipleUpdate(UPD_POSITION);
04284                 return true;
04285         }
04286 };
04287 
04288 // in order to link, all objects must have the same owner, and the
04289 // agent must have the ability to modify all of the objects. However,
04290 // we're not answering that question with this method. The question
04291 // we're answering is: does the user have a reasonable expectation
04292 // that a link operation should work? If so, return true, false
04293 // otherwise. this allows the handle_link method to more finely check
04294 // the selection and give an error message when the uer has a
04295 // reasonable expectation for the link to work, but it will fail.
04296 class LLToolsEnableLink : public view_listener_t
04297 {
04298         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04299         {
04300                 bool new_value = false;
04301                 // check if there are at least 2 objects selected, and that the
04302                 // user can modify at least one of the selected objects.
04303 
04304                 // in component mode, can't link
04305                 if (!gSavedSettings.getBOOL("EditLinkedParts"))
04306                 {
04307                         if(gSelectMgr->selectGetAllRootsValid() && gSelectMgr->getSelection()->getRootObjectCount() >= 2)
04308                         {
04309                                 struct f : public LLSelectedObjectFunctor
04310                                 {
04311                                         virtual bool apply(LLViewerObject* object)
04312                                         {
04313                                                 return object->permModify();
04314                                         }
04315                                 } func;
04316                                 const bool firstonly = true;
04317                                 new_value = gSelectMgr->getSelection()->applyToRootObjects(&func, firstonly);
04318                         }
04319                 }
04320                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04321                 return true;
04322         }
04323 };
04324 
04325 class LLToolsLink : public view_listener_t
04326 {
04327         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04328         {
04329                 if(!gSelectMgr->selectGetAllRootsValid())
04330                 {
04331                         LLNotifyBox::showXml("UnableToLinkWhileDownloading");
04332                         return true;
04333                 }
04334 
04335                 S32 object_count = gSelectMgr->getSelection()->getObjectCount();
04336                 if (object_count > MAX_CHILDREN_PER_TASK + 1)
04337                 {
04338                         LLStringBase<char>::format_map_t args;
04339                         args["[COUNT]"] = llformat("%d", object_count);
04340                         int max = MAX_CHILDREN_PER_TASK+1;
04341                         args["[MAX]"] = llformat("%d", max);
04342                         gViewerWindow->alertXml("UnableToLinkObjects", args);
04343                         return true;
04344                 }
04345 
04346                 if(gSelectMgr->getSelection()->getRootObjectCount() < 2)
04347                 {
04348                         gViewerWindow->alertXml("CannotLinkIncompleteSet");
04349                         return true;
04350                 }
04351                 if(!gSelectMgr->selectGetRootsModify())
04352                 {
04353                         gViewerWindow->alertXml("CannotLinkModify");
04354                         return true;
04355                 }
04356                 LLUUID owner_id;
04357                 LLString owner_name;
04358                 if(!gSelectMgr->selectGetOwner(owner_id, owner_name))
04359                 {
04360                         // we don't actually care if you're the owner, but novices are
04361                         // the most likely to be stumped by this one, so offer the
04362                         // easiest and most likely solution.
04363                         gViewerWindow->alertXml("CannotLinkDifferentOwners");
04364                         return true;
04365                 }
04366                 gSelectMgr->sendLink();
04367                 return true;
04368         }
04369 };
04370 
04371 class LLToolsEnableUnlink : public view_listener_t
04372 {
04373         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04374         {
04375                 bool new_value = gSelectMgr->selectGetAllRootsValid() &&
04376                         gSelectMgr->getSelection()->getFirstEditableObject() &&
04377                         !gSelectMgr->getSelection()->getFirstEditableObject()->isAttachment();
04378                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04379                 return true;
04380         }
04381 };
04382 
04383 class LLToolsUnlink : public view_listener_t
04384 {
04385         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04386         {
04387                 gSelectMgr->sendDelink();
04388                 return true;
04389         }
04390 };
04391 
04392 
04393 class LLToolsStopAllAnimations : public view_listener_t
04394 {
04395         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04396         {
04397                 LLVOAvatar* avatarp = gAgent.getAvatarObject();
04398                 
04399                 if (!avatarp) return true;
04400                 
04401                 avatarp->deactivateAllMotions();
04402         
04403                 avatarp->processAnimationStateChanges();
04404                 return true;
04405         }
04406 };
04407 
04408 //void handle_hinge(void*)
04409 //{
04410 //      gSelectMgr->sendHinge(1);
04411 //}
04412 
04413 //void handle_ptop(void*)
04414 //{
04415 //      gSelectMgr->sendHinge(2);
04416 //}
04417 
04418 //void handle_lptop(void*)
04419 //{
04420 //      gSelectMgr->sendHinge(3);
04421 //}
04422 
04423 //void handle_wheel(void*)
04424 //{
04425 //      gSelectMgr->sendHinge(4);
04426 //}
04427 
04428 //void handle_dehinge(void*)
04429 //{
04430 //      gSelectMgr->sendDehinge();
04431 //}
04432 
04433 //BOOL enable_dehinge(void*)
04434 //{
04435 //      LLViewerObject* obj = gSelectMgr->getSelection()->getFirstEditableObject();
04436 //      return obj && !obj->isAttachment();
04437 //}
04438 
04439 
04440 class LLEditEnableCut : public view_listener_t
04441 {
04442         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04443         {
04444                 bool new_value = gEditMenuHandler && gEditMenuHandler->canCut();
04445                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04446                 return true;
04447         }
04448 };
04449 
04450 class LLEditCut : public view_listener_t
04451 {
04452         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04453         {
04454                 if( gEditMenuHandler )
04455                 {
04456                         gEditMenuHandler->cut();
04457                 }
04458                 return true;
04459         }
04460 };
04461 
04462 class LLEditEnableCopy : public view_listener_t
04463 {
04464         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04465         {
04466                 bool new_value = gEditMenuHandler && gEditMenuHandler->canCopy();
04467                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04468                 return true;
04469         }
04470 };
04471 
04472 class LLEditCopy : public view_listener_t
04473 {
04474         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04475         {
04476                 if( gEditMenuHandler )
04477                 {
04478                         gEditMenuHandler->copy();
04479                 }
04480                 return true;
04481         }
04482 };
04483 
04484 class LLEditEnablePaste : public view_listener_t
04485 {
04486         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04487         {
04488                 bool new_value = gEditMenuHandler && gEditMenuHandler->canPaste();
04489                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04490                 return true;
04491         }
04492 };
04493 
04494 class LLEditPaste : public view_listener_t
04495 {
04496         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04497         {
04498                 if( gEditMenuHandler )
04499                 {
04500                         gEditMenuHandler->paste();
04501                 }
04502                 return true;
04503         }
04504 };
04505 
04506 class LLEditEnableDelete : public view_listener_t
04507 {
04508         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04509         {
04510                 bool new_value = gEditMenuHandler && gEditMenuHandler->canDoDelete();
04511                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04512                 return true;
04513         }
04514 };
04515 
04516 class LLEditDelete : public view_listener_t
04517 {
04518         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04519         {
04520                 // If a text field can do a deletion, it gets precedence over deleting
04521                 // an object in the world.
04522                 if( gEditMenuHandler && gEditMenuHandler->canDoDelete())
04523                 {
04524                         gEditMenuHandler->doDelete();
04525                 }
04526 
04527                 // and close any pie/context menus when done
04528                 gMenuHolder->hideMenus();
04529 
04530                 // When deleting an object we may not actually be done
04531                 // Keep selection so we know what to delete when confirmation is needed about the delete
04532                 gPieObject->hide(TRUE);
04533                 return true;
04534         }
04535 };
04536 
04537 class LLObjectEnableDelete : public view_listener_t
04538 {
04539         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04540         {
04541                 bool new_value = 
04542 #ifdef HACKED_GODLIKE_VIEWER
04543                         TRUE;
04544 #else
04545 # ifdef TOGGLE_HACKED_GODLIKE_VIEWER
04546                         (!gInProductionGrid && gAgent.isGodlike()) ||
04547 # endif
04548                         (gSelectMgr && gSelectMgr->canDoDelete());
04549 #endif
04550                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04551                 return true;
04552         }
04553 };
04554 
04555 class LLEditSearch : public view_listener_t
04556 {
04557         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04558         {
04559                 LLFloaterDirectory::toggleFind(NULL);
04560                 return true;
04561         }
04562 };
04563 
04564 class LLObjectDelete : public view_listener_t
04565 {
04566         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04567         {
04568                 if (gSelectMgr)
04569                 {
04570                         gSelectMgr->doDelete();
04571                 }
04572 
04573                 // and close any pie/context menus when done
04574                 gMenuHolder->hideMenus();
04575 
04576                 // When deleting an object we may not actually be done
04577                 // Keep selection so we know what to delete when confirmation is needed about the delete
04578                 gPieObject->hide(TRUE);
04579                 return true;
04580         }
04581 };
04582 
04583 void handle_force_delete(void*)
04584 {
04585         gSelectMgr->selectForceDelete();
04586 }
04587 
04588 class LLViewEnableLastChatter : public view_listener_t
04589 {
04590         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04591         {
04592                 // *TODO: add check that last chatter is in range
04593                 bool new_value = (gAgent.cameraThirdPerson() && gAgent.getLastChatter().notNull());
04594                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04595                 return true;
04596         }
04597 };
04598 
04599 class LLEditEnableDeselect : public view_listener_t
04600 {
04601         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04602         {
04603                 bool new_value = gEditMenuHandler && gEditMenuHandler->canDeselect();
04604                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04605                 return true;
04606         }
04607 };
04608 
04609 class LLEditDeselect : public view_listener_t
04610 {
04611         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04612         {
04613                 if( gEditMenuHandler )
04614                 {
04615                         gEditMenuHandler->deselect();
04616                 }
04617                 return true;
04618         }
04619 };
04620 
04621 class LLEditEnableSelectAll : public view_listener_t
04622 {
04623         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04624         {
04625                 bool new_value = gEditMenuHandler && gEditMenuHandler->canSelectAll();
04626                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04627                 return true;
04628         }
04629 };
04630 
04631 
04632 class LLEditSelectAll : public view_listener_t
04633 {
04634         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04635         {
04636                 if( gEditMenuHandler )
04637                 {
04638                         gEditMenuHandler->selectAll();
04639                 }
04640                 return true;
04641         }
04642 };
04643 
04644 
04645 class LLEditEnableUndo : public view_listener_t
04646 {
04647         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04648         {
04649                 bool new_value = gEditMenuHandler && gEditMenuHandler->canUndo();
04650                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04651                 return true;
04652         }
04653 };
04654 
04655 class LLEditUndo : public view_listener_t
04656 {
04657         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04658         {
04659                 if( gEditMenuHandler && gEditMenuHandler->canUndo() )
04660                 {
04661                         gEditMenuHandler->undo();
04662                 }
04663                 return true;
04664         }
04665 };
04666 
04667 class LLEditEnableRedo : public view_listener_t
04668 {
04669         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04670         {
04671                 bool new_value = gEditMenuHandler && gEditMenuHandler->canRedo();
04672                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04673                 return true;
04674         }
04675 };
04676 
04677 class LLEditRedo : public view_listener_t
04678 {
04679         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04680         {
04681                 if( gEditMenuHandler && gEditMenuHandler->canRedo() )
04682                 {
04683                         gEditMenuHandler->redo();
04684                 }
04685                 return true;
04686         }
04687 };
04688 
04689 
04690 
04691 void print_object_info(void*)
04692 {
04693         gSelectMgr->selectionDump();
04694 }
04695 
04696 
04697 void show_debug_menus()
04698 {
04699         // this can get called at login screen where there is no menu so only toggle it if one exists
04700         if ( gMenuBarView )
04701         {
04702                 BOOL debug = gSavedSettings.getBOOL("UseDebugMenus");
04703                 
04704                 if(debug)
04705                 {
04706                         LLFirstUse::useDebugMenus();
04707                 }
04708 
04709                 gMenuBarView->setItemVisible(CLIENT_MENU_NAME, debug);
04710                 gMenuBarView->setItemEnabled(CLIENT_MENU_NAME, debug);
04711                 gMenuBarView->setItemVisible(SERVER_MENU_NAME, debug);
04712                 gMenuBarView->setItemEnabled(SERVER_MENU_NAME, debug);
04713                 //gMenuBarView->setItemVisible(LLString("DebugOptions"),        visible);
04714                 //gMenuBarView->setItemVisible(LLString(AVI_TOOLS),     visible);
04715         };
04716 }
04717 
04718 void toggle_debug_menus(void*)
04719 {
04720         BOOL visible = ! gSavedSettings.getBOOL("UseDebugMenus");
04721         gSavedSettings.setBOOL("UseDebugMenus", visible);
04722         show_debug_menus();
04723 }
04724 
04725 
04726 void toggle_map( void* user_data )
04727 {
04728         // Toggle the item
04729         BOOL checked = gSavedSettings.getBOOL( static_cast<char*>(user_data) );
04730         gSavedSettings.setBOOL( static_cast<char*>(user_data), !checked );
04731         if (checked)
04732         {
04733                 gFloaterMap->close();
04734         }
04735         else
04736         {
04737                 gFloaterMap->open();            /* Flawfinder: ignore */        
04738         }
04739 }
04740 
04741 
04742 LLUUID gExporterRequestID;
04743 LLString gExportDirectory;
04744 
04745 LLUploadDialog *gExportDialog = NULL;
04746 
04747 void handle_export_selected( void * )
04748 {
04749         LLObjectSelectionHandle selection = gSelectMgr->getSelection();
04750         if (selection->isEmpty())
04751         {
04752                 return;
04753         }
04754         llinfos << "Exporting selected objects:" << llendl;
04755 
04756         gExporterRequestID.generate();
04757         gExportDirectory = "";
04758 
04759         LLMessageSystem* msg = gMessageSystem;
04760         msg->newMessageFast(_PREHASH_ObjectExportSelected);
04761         msg->nextBlockFast(_PREHASH_AgentData);
04762         msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
04763         msg->addUUIDFast(_PREHASH_RequestID, gExporterRequestID);
04764         msg->addS16Fast(_PREHASH_VolumeDetail, 4);
04765 
04766         for (LLObjectSelection::root_iterator iter = selection->root_begin();
04767                  iter != selection->root_end(); iter++)
04768         {
04769                 LLSelectNode* node = *iter;
04770                 LLViewerObject* object = node->getObject();
04771                 msg->nextBlockFast(_PREHASH_ObjectData);
04772                 msg->addUUIDFast(_PREHASH_ObjectID, object->getID());
04773                 llinfos << "Object: " << object->getID() << llendl;
04774         }
04775         msg->sendReliable(gAgent.getRegion()->getHost());
04776 
04777         gExportDialog = LLUploadDialog::modalUploadDialog("Exporting selected objects...");
04778 }
04779 
04780 BOOL menu_check_build_tool( void* user_data )
04781 {
04782         S32 index = (intptr_t) user_data;
04783         return gToolMgr->getCurrentToolset()->isToolSelected( index );
04784 }
04785 
04786 void handle_reload_settings(void*)
04787 {
04788         gSavedSettings.resetToDefaults();
04789         gSavedSettings.loadFromFile(gSettingsFileName, TRUE);
04790 
04791         llinfos << "Loading colors from colors.xml" << llendl;
04792         std::string color_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"colors.xml");
04793         gColors.resetToDefaults();
04794         gColors.loadFromFile(color_file, FALSE, TYPE_COL4U);
04795 }
04796 
04797 class LLWorldSetHomeLocation : public view_listener_t
04798 {
04799         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04800         {
04801                 // we just send the message and let the server check for failure cases
04802                 // server will echo back a "Home position set." alert if it succeeds
04803                 // and the home location screencapture happens when that alert is recieved
04804                 gAgent.setStartPosition(START_LOCATION_ID_HOME);
04805                 return true;
04806         }
04807 };
04808 
04809 class LLWorldTeleportHome : public view_listener_t
04810 {
04811         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04812         {
04813                 gAgent.teleportHome();
04814                 return true;
04815         }
04816 };
04817 
04818 class LLWorldAlwaysRun : public view_listener_t
04819 {
04820         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04821         {
04822                 if (gAgent.getAlwaysRun())
04823                 {
04824                         gAgent.clearAlwaysRun();
04825                 }
04826                 else
04827                 {
04828                         gAgent.setAlwaysRun();
04829                 }
04830                 LLMessageSystem *msg = gMessageSystem;
04831 
04832 
04833                 msg->newMessageFast(_PREHASH_SetAlwaysRun);
04834                 msg->nextBlockFast(_PREHASH_AgentData);
04835                 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
04836                 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
04837                 msg->addBOOLFast(_PREHASH_AlwaysRun, gAgent.getAlwaysRun() );
04838                 gAgent.sendReliableMessage();
04839                 return true;
04840         }
04841 };
04842 
04843 class LLWorldCheckAlwaysRun : public view_listener_t
04844 {
04845         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04846         {
04847                 bool new_value = gAgent.getAlwaysRun();
04848                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
04849                 return true;
04850         }
04851 };
04852 
04853 class LLWorldSetAway : public view_listener_t
04854 {
04855         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04856         {
04857                 if (gAgent.getAFK())
04858                 {
04859                         gAgent.clearAFK();
04860                 }
04861                 else
04862                 {
04863                         gAgent.setAFK();
04864                 }
04865                 return true;
04866         }
04867 };
04868 
04869 class LLWorldSetBusy : public view_listener_t
04870 {
04871         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04872         {
04873                 if (gAgent.getBusy())
04874                 {
04875                         gAgent.clearBusy();
04876                 }
04877                 else
04878                 {
04879                         gAgent.setBusy();
04880                         gViewerWindow->alertXml("BusyModeSet");
04881                 }
04882                 return true;
04883         }
04884 };
04885 
04886 
04887 class LLWorldCreateLandmark : public view_listener_t
04888 {
04889         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04890         {
04891                 LLViewerRegion* agent_region = gAgent.getRegion();
04892                 if(!agent_region)
04893                 {
04894                         llwarns << "No agent region" << llendl;
04895                         return true;
04896                 }
04897                 LLParcel* agent_parcel = gParcelMgr->getAgentParcel();
04898                 if (!agent_parcel)
04899                 {
04900                         llwarns << "No agent parcel" << llendl;
04901                         return true;
04902                 }
04903                 if (!agent_parcel->getAllowLandmark()
04904                         && !LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
04905                 {
04906                         gViewerWindow->alertXml("CannotCreateLandmarkNotOwner");
04907                         return true;
04908                 }
04909 
04910                 LLUUID folder_id;
04911                 folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
04912                 std::string pos_string;
04913                 gAgent.buildLocationString(pos_string);
04914                 
04915                 create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
04916                                                           folder_id, LLTransactionID::tnull,
04917                                                           pos_string, pos_string, // name, desc
04918                                                           LLAssetType::AT_LANDMARK,
04919                                                           LLInventoryType::IT_LANDMARK,
04920                                                           NOT_WEARABLE, PERM_ALL, 
04921                                                           NULL);
04922                 return true;
04923         }
04924 };
04925 
04926 class LLToolsLookAtSelection : public view_listener_t
04927 {
04928         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04929         {
04930                 const F32 PADDING_FACTOR = 2.f;
04931                 BOOL zoom = (userdata.asString() == "zoom");
04932                 if (!gSelectMgr->getSelection()->isEmpty())
04933                 {
04934                         gAgent.setFocusOnAvatar(FALSE, ANIMATE);
04935 
04936                         LLBBox selection_bbox = gSelectMgr->getBBoxOfSelection();
04937                         F32 angle_of_view = llmax(0.1f, gCamera->getAspect() > 1.f ? gCamera->getView() * gCamera->getAspect() : gCamera->getView());
04938                         F32 distance = selection_bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view);
04939 
04940                         LLVector3 obj_to_cam = gCamera->getOrigin() - selection_bbox.getCenterAgent();
04941                         obj_to_cam.normVec();
04942 
04943                         if (zoom)
04944                         {
04945                                 gAgent.setCameraPosAndFocusGlobal(gSelectMgr->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance), gSelectMgr->getSelectionCenterGlobal(), gSelectMgr->getSelection()->getFirstObject()->mID );
04946                         }
04947                         else
04948                         {
04949                                 gAgent.setFocusGlobal( gSelectMgr->getSelectionCenterGlobal(), gSelectMgr->getSelection()->getFirstObject()->mID );
04950                         }
04951                 }
04952                 return true;
04953         }
04954 };
04955 
04956 void callback_invite_to_group(LLUUID group_id, void *user_data)
04957 {
04958         std::vector<LLUUID> agent_ids;
04959         agent_ids.push_back(*(LLUUID *)user_data);
04960         
04961         LLFloaterGroupInvite::showForGroup(group_id, &agent_ids);
04962 }
04963 
04964 void invite_to_group(const LLUUID& dest_id)
04965 {
04966         LLViewerObject* dest = gObjectList.findObject(dest_id);
04967         if(dest && dest->isAvatar())
04968         {
04969                 LLFloaterGroupPicker* widget;
04970                 widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
04971                 if (widget)
04972                 {
04973                         widget->center();
04974                         widget->setPowersMask(GP_MEMBER_INVITE);
04975                         widget->setSelectCallback(callback_invite_to_group, (void *)&dest_id);
04976                 }
04977         }
04978 }
04979 
04980 class LLAvatarInviteToGroup : public view_listener_t
04981 {
04982         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04983         {
04984                 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
04985                 if(avatar)
04986                 {
04987                         invite_to_group(avatar->getID());
04988                 }
04989                 return true;
04990         }
04991 };
04992 
04993 class LLAvatarAddFriend : public view_listener_t
04994 {
04995         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
04996         {
04997                 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
04998                 if(avatar && !is_agent_friend(avatar->getID()))
04999                 {
05000                         request_friendship(avatar->getID());
05001                 }
05002                 return true;
05003         }
05004 };
05005 
05006 void complete_give_money(S32 option, void* user_data)
05007 {
05008         if (option == 0)
05009         {
05010                 gAgent.clearBusy();
05011         }
05012 
05013         LLObjectSelectionHandle handle(*(LLObjectSelectionHandle*)user_data);
05014         delete (LLObjectSelectionHandle*)user_data;
05015 
05016         LLViewerObject* objectp = handle->getPrimaryObject();
05017 
05018         // Show avatar's name if paying attachment
05019         if (objectp && objectp->isAttachment())
05020         {
05021                 while (objectp && !objectp->isAvatar())
05022                 {
05023                         objectp = (LLViewerObject*)objectp->getParent();
05024                 }
05025         }
05026 
05027         if (objectp)
05028         {
05029                 if (objectp->isAvatar())
05030                 {
05031                         const BOOL is_group = FALSE;
05032                         LLFloaterPay::payDirectly(&give_money,
05033                                                                           objectp->getID(),
05034                                                                           is_group);
05035                 }
05036                 else
05037                 {
05038                         LLFloaterPay::payViaObject(&give_money, objectp->getID());
05039                 }
05040         }
05041 }
05042 
05043 bool handle_give_money_dialog()
05044 {
05045         LLObjectSelectionHandle* handlep = new LLObjectSelectionHandle(gSelectMgr->getSelection());
05046         if (gAgent.getBusy())
05047         {
05048                 // warn users of being in busy mode during a transaction
05049                 gViewerWindow->alertXml("BusyModePay", complete_give_money, handlep);
05050         }
05051         else
05052         {
05053                 complete_give_money(1, handlep);
05054         }
05055         return true;
05056 }
05057 
05058 class LLPayObject : public view_listener_t
05059 {
05060         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05061         {
05062                 return handle_give_money_dialog();
05063         }
05064 };
05065 
05066 class LLEnablePayObject : public view_listener_t
05067 {
05068         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05069         {
05070                 LLVOAvatar* avatar = find_avatar_from_object(gViewerWindow->lastObjectHit());
05071                 bool new_value = (avatar != NULL);
05072                 if (!new_value)
05073                 {
05074                         LLViewerObject* object = gViewerWindow->lastObjectHit();
05075                         if( object )
05076                         {
05077                                 LLViewerObject *parent = (LLViewerObject *)object->getParent();
05078                                 if((object->flagTakesMoney()) || (parent && parent->flagTakesMoney()))
05079                                 {
05080                                         new_value = true;
05081                                 }
05082                         }
05083                 }
05084                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
05085                 return true;
05086         }
05087 };
05088 
05089 class LLObjectEnableSitOrStand : public view_listener_t
05090 {
05091         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05092         {
05093                 bool new_value = false;
05094                 LLViewerObject* dest_object = NULL;
05095                 if((dest_object = gObjectList.findObject(gLastHitObjectID)))
05096                 {
05097                         if(dest_object->getPCode() == LL_PCODE_VOLUME)
05098                         {
05099                                 new_value = true;
05100                         }
05101                 }
05102                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
05103 
05104                 // Update label
05105                 LLString label;
05106                 LLString sit_text;
05107                 LLString stand_text;
05108                 LLString param = userdata["data"].asString();
05109                 LLString::size_type offset = param.find(",");
05110                 if (offset != param.npos)
05111                 {
05112                         sit_text = param.substr(0, offset);
05113                         stand_text = param.substr(offset+1);
05114                 }
05115                 if (sitting_on_selection())
05116                 {
05117                         label = stand_text;
05118                 }
05119                 else
05120                 {
05121                         LLSelectNode* node = gSelectMgr->getSelection()->getFirstRootNode();
05122                         if (node && node->mValid && !node->mSitName.empty())
05123                         {
05124                                 label.assign(node->mSitName);
05125                         }
05126                         else
05127                         {
05128                                 label = sit_text;
05129                         }
05130                 }
05131                 gMenuHolder->childSetText("Object Sit", label);
05132 
05133                 return true;
05134         }
05135 };
05136 
05137 void edit_ui(void*)
05138 {
05139         LLFloater::setEditModeEnabled(!LLFloater::getEditModeEnabled());
05140 }
05141 
05142 void dump_select_mgr(void*)
05143 {
05144         gSelectMgr->dump();
05145 }
05146 
05147 void dump_volume_mgr(void*)
05148 {
05149         gVolumeMgr->dump();
05150 }
05151 
05152 void dump_inventory(void*)
05153 {
05154         gInventory.dumpInventory();
05155 }
05156 
05157 // forcibly unlock an object
05158 void handle_force_unlock(void*)
05159 {
05160         // First, make it public.
05161         gSelectMgr->sendOwner(LLUUID::null, LLUUID::null, TRUE);
05162 
05163         // Second, lie to the viewer and mark it editable and unowned
05164 
05165         struct f : public LLSelectedObjectFunctor
05166         {
05167                 virtual bool apply(LLViewerObject* object)
05168                 {
05169                         object->mFlags |= FLAGS_OBJECT_MOVE;
05170                         object->mFlags |= FLAGS_OBJECT_MODIFY;
05171                         object->mFlags |= FLAGS_OBJECT_COPY;
05172 
05173                         object->mFlags &= ~FLAGS_OBJECT_ANY_OWNER;
05174                         object->mFlags &= ~FLAGS_OBJECT_YOU_OWNER;
05175                         return true;
05176                 }
05177         } func;
05178         gSelectMgr->getSelection()->applyToObjects(&func);
05179 }
05180 
05181 // Fullscreen debug stuff
05182 void handle_fullscreen_debug(void*)
05183 {
05184         llinfos << "Width " << gViewerWindow->getWindowWidth() << " Height " << gViewerWindow->getWindowHeight() << llendl;
05185         llinfos << "mouse_x_from_center(100) " << mouse_x_from_center(100) << " y " << mouse_y_from_center(100) << llendl;
05186 }
05187 
05188 void handle_crash(void*)
05189 {
05190         llerrs << "This is an llerror" << llendl;
05191 }
05192 
05193 class LLWorldForceSun : public view_listener_t
05194 {
05195         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05196         {
05197                 LLString tod = userdata.asString();
05198                 LLVector3 sun_direction;
05199                 if (tod == "sunrise")
05200                 {
05201                         sun_direction.setVec(1.0f, 0.f, 0.2f);
05202                 }
05203                 else if (tod == "noon")
05204                 {
05205                         sun_direction.setVec(0.0f, 0.3f, 1.0f);
05206                 }
05207                 else if (tod == "sunset")
05208                 {
05209                         sun_direction.setVec(-1.0f, 0.f, 0.2f);
05210                 }
05211                 else if (tod == "midnight")
05212                 {
05213                         sun_direction.setVec(0.0f, 0.3f, -1.0f);
05214                 }
05215                 else
05216                 {
05217                         gSky.setOverrideSun(FALSE);
05218                         return true;
05219                 }
05220                 sun_direction.normVec();
05221                 gSky.setOverrideSun(TRUE);
05222                 gSky.setSunDirection( sun_direction, LLVector3(0.f, 0.f, 0.f));
05223                 return true;
05224         }
05225 };
05226 
05227 void handle_dump_followcam(void*)
05228 {
05229         LLFollowCamMgr::dump();
05230 }
05231 
05232 BOOL check_flycam(void*)
05233 {
05234         return LLViewerJoystick::sOverrideCamera;
05235 }
05236 
05237 void handle_toggle_flycam(void*)
05238 {
05239         LLViewerJoystick::sOverrideCamera = !LLViewerJoystick::sOverrideCamera;
05240         if (LLViewerJoystick::sOverrideCamera)
05241         {
05242                 LLViewerJoystick::updateCamera(TRUE);
05243                 LLFloaterJoystick::show(NULL);
05244         }
05245 }
05246 
05247 void handle_viewer_enable_message_log(void*)
05248 {
05249         gMessageSystem->startLogging();
05250 }
05251 
05252 void handle_viewer_disable_message_log(void*)
05253 {
05254         gMessageSystem->stopLogging();
05255 }
05256 
05257 // TomY TODO: Move!
05258 class LLShowFloater : public view_listener_t
05259 {
05260         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05261         {
05262                 LLString floater_name = userdata.asString();
05263                 if (floater_name == "gestures")
05264                 {
05265                         LLFloaterGesture::toggleVisibility();
05266                 }
05267                 else if (floater_name == "appearance")
05268                 {
05269                         if (gAgent.getWearablesLoaded())
05270                         {
05271                                 gAgent.changeCameraToCustomizeAvatar();
05272                         }
05273                 }
05274                 else if (floater_name == "friends")
05275                 {
05276                         LLFloaterMyFriends::toggleInstance(0);
05277                 }
05278                 else if (floater_name == "preferences")
05279                 {
05280                         LLFloaterPreference::show(NULL);
05281                 }
05282                 else if (floater_name == "toolbar")
05283                 {
05284                         LLToolBar::toggle(NULL);
05285                 }
05286                 else if (floater_name == "chat history")
05287                 {
05288                         LLFloaterChat::toggleInstance(LLSD());
05289                 }
05290                 else if (floater_name == "im")
05291                 {
05292                         LLFloaterChatterBox::toggleInstance(LLSD());
05293                 }
05294                 else if (floater_name == "inventory")
05295                 {
05296                         LLInventoryView::toggleVisibility(NULL);
05297                 }
05298                 else if (floater_name == "mute list")
05299                 {
05300                         LLFloaterMute::toggle(NULL);
05301                 }
05302                 else if (floater_name == "camera controls")
05303                 {
05304                         LLFloaterCamera::toggle(NULL);
05305                 }
05306                 else if (floater_name == "movement controls")
05307                 {
05308                         LLFloaterMove::show(NULL);
05309                 }
05310                 else if (floater_name == "world map")
05311                 {
05312                         LLFloaterWorldMap::toggle(NULL);
05313                 }
05314                 else if (floater_name == "mini map")
05315                 {
05316                         LLFloaterMap::toggle(NULL);
05317                 }
05318                 else if (floater_name == "stat bar")
05319                 {
05320                         gDebugView->mStatViewp->setVisible(!gDebugView->mStatViewp->getVisible());
05321                 }
05322                 else if (floater_name == "my land")
05323                 {
05324                         LLFloaterLandHoldings::show(NULL);
05325                 }
05326                 else if (floater_name == "about land")
05327                 {
05328                         if (gParcelMgr->selectionEmpty())
05329                         {
05330                                 gParcelMgr->selectParcelAt(gAgent.getPositionGlobal());
05331                         }
05332 
05333                         LLFloaterLand::show();
05334                 }
05335                 else if (floater_name == "buy land")
05336                 {
05337                         if (gParcelMgr->selectionEmpty())
05338                         {
05339                                 gParcelMgr->selectParcelAt(gAgent.getPositionGlobal());
05340                         }
05341                         
05342                         gParcelMgr->startBuyLand();
05343                 }
05344                 else if (floater_name == "about region")
05345                 {
05346                         LLFloaterRegionInfo::show((void *)NULL);
05347                 }
05348                 else if (floater_name == "grid options")
05349                 {
05350                         LLFloaterBuildOptions::show(NULL);
05351                 }
05352                 else if (floater_name == "script errors")
05353                 {
05354                         LLFloaterScriptDebug::show(LLUUID::null);
05355                 }
05356                 else if (floater_name == "help f1")
05357                 {
05358 #if LL_LIBXUL_ENABLED
05359                         gViewerHtmlHelp.show( gSavedSettings.getString("HelpHomeURL") );
05360 #endif
05361                 }
05362                 else if (floater_name == "help in-world")
05363                 {
05364 #if LL_LIBXUL_ENABLED
05365                         LLFloaterHtml::getInstance()->show( "in-world_help" );
05366 #endif
05367                 }
05368                 else if (floater_name == "help additional")
05369                 {
05370 #if LL_LIBXUL_ENABLED
05371                         LLFloaterHtml::getInstance()->show( "additional_help" );
05372 #endif
05373                 }
05374                 else if (floater_name == "complaint reporter")
05375                 {
05376                         // Prevent menu from appearing in screen shot.
05377                         gMenuHolder->hideMenus();
05378                         LLFloaterReporter::showFromMenu(COMPLAINT_REPORT);
05379                 }
05380                 else if (floater_name == "mean events")
05381                 {
05382                         if (!gNoRender)
05383                         {
05384                                 LLFloaterBump::show(NULL);
05385                         }
05386                 }
05387                 else if (floater_name == "lag meter")
05388                 {
05389                         LLFloaterLagMeter::show(NULL);
05390                 }
05391                 else if (floater_name == "bug reporter")
05392                 {
05393                         // Prevent menu from appearing in screen shot.
05394                         gMenuHolder->hideMenus();
05395                         LLFloaterReporter::showFromMenu(BUG_REPORT);
05396                 }
05397                 else if (floater_name == "buy currency")
05398                 {
05399                         LLFloaterBuyCurrency::buyCurrency();
05400                 }
05401                 else if (floater_name == "about")
05402                 {
05403                         LLFloaterAbout::show(NULL);
05404                 }
05405                 else if (floater_name == "avatar list")
05406                 {
05407                         LLFloaterAvatarList::toggle(NULL);
05408                 }
05409                 else if (floater_name == "event log")
05410                 {
05411                         LLFloaterEventLog::toggle(NULL);
05412                 }
05413                 else if (floater_name == "active speakers")
05414                 {
05415                         LLFloaterActiveSpeakers::toggleInstance(LLSD());
05416                 }
05417                 else if (floater_name == "project")
05418                 {
05419                         LLFloaterNetwork2080::toggle(NULL);
05420                 }
05421                 return true;
05422         }
05423 };
05424 
05425 class LLFloaterVisible : public view_listener_t
05426 {
05427         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05428         {
05429                 LLString control_name = userdata["control"].asString();
05430                 LLString floater_name = userdata["data"].asString();
05431                 bool new_value = false;
05432                 if (floater_name == "friends")
05433                 {
05434                         new_value = LLFloaterMyFriends::instanceVisible(0);
05435                 }
05436                 else if (floater_name == "toolbar")
05437                 {
05438                         new_value = LLToolBar::visible(NULL);
05439                 }
05440                 else if (floater_name == "chat history")
05441                 {
05442                         new_value = LLFloaterChat::visible(NULL);
05443                 }
05444                 else if (floater_name == "im")
05445                 {
05446                         new_value = LLFloaterMyFriends::instanceVisible(0);
05447                 }
05448                 else if (floater_name == "mute list")
05449                 {
05450                         new_value = LLFloaterMute::visible(NULL);
05451                 }
05452                 else if (floater_name == "camera controls")
05453                 {
05454                         new_value = LLFloaterCamera::visible(NULL);
05455                 }
05456                 else if (floater_name == "movement controls")
05457                 {
05458                         new_value = LLFloaterMove::visible(NULL);
05459                 }
05460                 else if (floater_name == "stat bar")
05461                 {
05462                         new_value = gDebugView->mStatViewp->getVisible();
05463                 }
05464                 else if (floater_name == "active speakers")
05465                 {
05466                         new_value = LLFloaterActiveSpeakers::instanceVisible(LLSD());
05467                 }
05468                 gMenuHolder->findControl(control_name)->setValue(new_value);
05469                 return true;
05470         }
05471 };
05472 
05473 void callback_show_url(S32 option, void* url)
05474 {
05475         const char* urlp = (const char*)url;
05476         if (0 == option)
05477         {
05478                 LLWeb::loadURL(urlp);
05479         }
05480         delete urlp;
05481 }
05482 
05483 class LLPromptShowURL : public view_listener_t
05484 {
05485         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05486         {
05487                 LLString param = userdata.asString();
05488                 LLString::size_type offset = param.find(",");
05489                 if (offset != param.npos)
05490                 {
05491                         LLString alert = param.substr(0, offset);
05492                         LLString url = param.substr(offset+1);
05493                         char *url_copy = new char[url.size()+1];
05494                         if (url_copy != NULL)
05495                         {
05496                                 strcpy(url_copy, url.c_str());          /* Flawfinder: ignore */
05497                         }
05498                         else
05499                         {
05500                                 llerrs << "Memory Allocation Failed" << llendl;
05501                                 return false;
05502                         }
05503                         gViewerWindow->alertXml(alert, callback_show_url, url_copy);
05504                 }
05505                 else
05506                 {
05507                         llinfos << "PromptShowURL invalid parameters! Expecting \"ALERT,URL\"." << llendl;
05508                 }
05509                 return true;
05510         }
05511 };
05512 
05513 void callback_show_file(S32 option, void* filename)
05514 {
05515         const char* filenamep = (const char*)filename;
05516         if (0 == option)
05517         {
05518                 load_url_local_file(filenamep);
05519         }
05520         delete filenamep;
05521 }
05522 
05523 class LLPromptShowFile : public view_listener_t
05524 {
05525         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05526         {
05527                 LLString param = userdata.asString();
05528                 LLString::size_type offset = param.find(",");
05529                 if (offset != param.npos)
05530                 {
05531                         LLString alert = param.substr(0, offset);
05532                         LLString file = param.substr(offset+1);
05533                         char *file_copy = new char[file.size()+1];
05534                         if (file_copy != NULL)
05535                         {
05536                                 strcpy(file_copy, file.c_str());                /* Flawfinder: ignore */
05537                         }
05538                         else
05539                         {
05540                                 llerrs << "Memory Allocation Failed" << llendl;
05541                                 return false;
05542                         }
05543                         gViewerWindow->alertXml(alert, callback_show_file, file_copy);
05544                 }
05545                 else
05546                 {
05547                         llinfos << "PromptShowFile invalid parameters! Expecting \"ALERT,FILE\"." << llendl;
05548                 }
05549                 return true;
05550         }
05551 };
05552 
05553 class LLShowAgentProfile : public view_listener_t
05554 {
05555         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05556         {
05557                 LLUUID agent_id;
05558                 if (userdata.asString() == "agent")
05559                 {
05560                         agent_id = gAgent.getID();
05561                 }
05562                 else if (userdata.asString() == "hit object")
05563                 {
05564                         agent_id = gLastHitObjectID;
05565                 }
05566                 else
05567                 {
05568                         agent_id = userdata.asUUID();
05569                 }
05570 
05571                 LLVOAvatar* avatar = find_avatar_from_object(agent_id);
05572                 if (avatar)
05573                 {
05574                         LLFloaterAvatarInfo::show( avatar->getID() );
05575                 }
05576                 return true;
05577         }
05578 };
05579 
05580 class LLShowAgentGroups : public view_listener_t
05581 {
05582         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05583         {
05584                 LLFloaterMyFriends::toggleInstance(1);
05585                 return true;
05586         }
05587 };
05588 
05589 void handle_focus(void *)
05590 {
05591         if (gDisconnected)
05592         {
05593                 return;
05594         }
05595 
05596         if (gAgent.getFocusOnAvatar())
05597         {
05598                 // zoom in if we're looking at the avatar
05599                 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
05600                 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
05601                 gAgent.cameraZoomIn(0.666f);
05602         }
05603         else
05604         {
05605                 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
05606         }
05607 
05608         gViewerWindow->moveCursorToCenter();
05609 
05610         // Switch to camera toolset
05611 //      gToolMgr->setCurrentToolset(gCameraToolset);
05612         gToolMgr->getCurrentToolset()->selectTool( gToolCamera );
05613 }
05614 
05615 class LLLandEdit : public view_listener_t
05616 {
05617         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05618         {
05619                 if (gAgent.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") )
05620                 {
05621                         // zoom in if we're looking at the avatar
05622                         gAgent.setFocusOnAvatar(FALSE, ANIMATE);
05623                         gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
05624 
05625                         gAgent.cameraOrbitOver( F_PI * 0.25f );
05626                         gViewerWindow->moveCursorToCenter();
05627                 }
05628                 else if ( gSavedSettings.getBOOL("EditCameraMovement") )
05629                 {
05630                         gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
05631                         gViewerWindow->moveCursorToCenter();
05632                 }
05633 
05634 
05635                 gParcelMgr->selectParcelAt( gLastHitPosGlobal );
05636 
05637                 gFloaterTools->showMore(TRUE);
05638                 gFloaterView->bringToFront( gFloaterTools );
05639 
05640                 // Switch to land edit toolset
05641                 gToolMgr->getCurrentToolset()->selectTool( gToolParcel );
05642                 return true;
05643         }
05644 };
05645 
05646 class LLWorldEnableBuyLand : public view_listener_t
05647 {
05648         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05649         {
05650                 bool new_value = gParcelMgr->canAgentBuyParcel(
05651                                                                 gParcelMgr->selectionEmpty()
05652                                                                         ? gParcelMgr->getAgentParcel()
05653                                                                         : gParcelMgr->getParcelSelection()->getParcel(),
05654                                                                 false);
05655                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
05656                 return true;
05657         }
05658 };
05659 
05660 BOOL enable_buy_land(void*)
05661 {
05662         return gParcelMgr->canAgentBuyParcel(
05663                                 gParcelMgr->getParcelSelection()->getParcel(), false);
05664 }
05665 
05666 
05667 void handle_move(void*)
05668 {
05669         if (gAgent.getFocusOnAvatar())
05670         {
05671                 // zoom in if we're looking at the avatar
05672                 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
05673                 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
05674 
05675                 gAgent.cameraZoomIn(0.666f);
05676         }
05677         else
05678         {
05679                 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
05680         }
05681 
05682         gViewerWindow->moveCursorToCenter();
05683 
05684         gToolMgr->setCurrentToolset(gBasicToolset);
05685         gToolMgr->getCurrentToolset()->selectTool( gToolGrab );
05686 }
05687 
05688 class LLObjectAttachToAvatar : public view_listener_t
05689 {
05690 public:
05691         static void setObjectSelection(LLObjectSelectionHandle selection) { sObjectSelection = selection; }
05692 
05693 private:
05694         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05695         {
05696                 setObjectSelection(gSelectMgr->getSelection());
05697                 LLViewerObject* selectedObject = sObjectSelection->getFirstRootObject();
05698                 if (selectedObject)
05699                 {
05700                         S32 index = userdata.asInteger();
05701                         LLViewerJointAttachment* attachment_point = index > 0 ?
05702                                 gAgent.getAvatarObject()->mAttachmentPoints[index] :
05703                                 NULL;
05704                         confirm_replace_attachment(0, attachment_point);
05705                 }
05706                 return true;
05707         }
05708 
05709 protected:
05710         static LLObjectSelectionHandle sObjectSelection;
05711 };
05712 
05713 LLObjectSelectionHandle LLObjectAttachToAvatar::sObjectSelection;
05714 
05715 void near_attach_object(BOOL success, void *user_data)
05716 {
05717         if (success)
05718         {
05719                 LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
05720                 
05721                 U8 attachment_id;
05722                 if (attachment)
05723                 {
05724                         attachment_id = gAgent.getAvatarObject()->mAttachmentPoints.reverseLookup(attachment);
05725                 }
05726                 else
05727                 {
05728                         // interpret 0 as "default location"
05729                         attachment_id = 0;
05730                 }
05731                 gSelectMgr->sendAttach(attachment_id);
05732         }               
05733         LLObjectAttachToAvatar::setObjectSelection(NULL);
05734 }
05735 
05736 void confirm_replace_attachment(S32 option, void* user_data)
05737 {
05738         if (option == 0/*YES*/)
05739         {
05740                 LLViewerObject* selectedObject = gSelectMgr->getSelection()->getFirstRootObject();
05741                 if (selectedObject)
05742                 {
05743                         const F32 MIN_STOP_DISTANCE = 1.f;      // meters
05744                         const F32 ARM_LENGTH = 0.5f;            // meters
05745                         const F32 SCALE_FUDGE = 1.5f;
05746 
05747                         F32 stop_distance = SCALE_FUDGE * selectedObject->getMaxScale() + ARM_LENGTH;
05748                         if (stop_distance < MIN_STOP_DISTANCE)
05749                         {
05750                                 stop_distance = MIN_STOP_DISTANCE;
05751                         }
05752 
05753                         LLVector3 walkToSpot = selectedObject->getPositionAgent();
05754                         
05755                         // make sure we stop in front of the object
05756                         LLVector3 delta = walkToSpot - gAgent.getPositionAgent();
05757                         delta.normVec();
05758                         delta = delta * 0.5f;
05759                         walkToSpot -= delta;
05760 
05761                         gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, near_attach_object, user_data, stop_distance);
05762                         gAgent.clearFocusObject();
05763                 }
05764         }
05765 }
05766 
05767 class LLAttachmentDrop : public view_listener_t
05768 {
05769         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05770         {
05771                 // Called when the user clicked on an object attached to them
05772                 // and selected "Drop".
05773                 LLViewerObject *object = gViewerWindow->lastObjectHit();
05774                 if (!object)
05775                 {
05776                         llwarns << "handle_drop_attachment() - no object to drop" << llendl;
05777                         return true;
05778                 }
05779 
05780                 LLViewerObject *parent = (LLViewerObject*)object->getParent();
05781                 while (parent)
05782                 {
05783                         if(parent->isAvatar())
05784                         {
05785                                 break;
05786                         }
05787                         object = parent;
05788                         parent = (LLViewerObject*)parent->getParent();
05789                 }
05790 
05791                 if (!object)
05792                 {
05793                         llwarns << "handle_detach() - no object to detach" << llendl;
05794                         return true;
05795                 }
05796 
05797                 if (object->isAvatar())
05798                 {
05799                         llwarns << "Trying to detach avatar from avatar." << llendl;
05800                         return true;
05801                 }
05802 
05803                 // The sendDropAttachment() method works on the list of selected
05804                 // objects.  Thus we need to clear the list, make sure it only
05805                 // contains the object the user clicked, send the message,
05806                 // then clear the list.
05807                 gSelectMgr->sendDropAttachment();
05808                 return true;
05809         }
05810 };
05811 
05812 // called from avatar pie menu
05813 void handle_detach_from_avatar(void* user_data)
05814 {
05815         LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
05816         
05817         LLViewerObject* attached_object = attachment->getObject();
05818 
05819         if (attached_object)
05820         {
05821                 gMessageSystem->newMessage("ObjectDetach");
05822                 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
05823                 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
05824                 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
05825 
05826                 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
05827                 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID());
05828                 gMessageSystem->sendReliable( gAgent.getRegionHost() );
05829         }
05830 }
05831 
05832 void attach_label(LLString& label, void* user_data)
05833 {
05834         LLViewerJointAttachment* attachmentp = (LLViewerJointAttachment*)user_data;
05835         if (attachmentp)
05836         {
05837                 label = attachmentp->getName();
05838                 if (attachmentp->getObject())
05839                 {
05840                         LLViewerInventoryItem* itemp = gInventory.getItem(attachmentp->getItemID());
05841                         if (itemp)
05842                         {
05843                                 label += LLString(" (") + itemp->getName() + LLString(")");
05844                         }
05845                 }
05846         }
05847 }
05848 
05849 void detach_label(LLString& label, void* user_data)
05850 {
05851         LLViewerJointAttachment* attachmentp = (LLViewerJointAttachment*)user_data;
05852         if (attachmentp)
05853         {
05854                 label = attachmentp->getName();
05855                 if (attachmentp->getObject())
05856                 {
05857                         LLViewerInventoryItem* itemp = gInventory.getItem(attachmentp->getItemID());
05858                         if (itemp)
05859                         {
05860                                 label += LLString(" (") + itemp->getName() + LLString(")");
05861                         }
05862                 }
05863         }
05864 }
05865 
05866 
05867 class LLAttachmentDetach : public view_listener_t
05868 {
05869         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05870         {
05871                 // Called when the user clicked on an object attached to them
05872                 // and selected "Detach".
05873                 LLViewerObject *object = gViewerWindow->lastObjectHit();
05874                 if (!object)
05875                 {
05876                         llwarns << "handle_detach() - no object to detach" << llendl;
05877                         return true;
05878                 }
05879 
05880                 LLViewerObject *parent = (LLViewerObject*)object->getParent();
05881                 while (parent)
05882                 {
05883                         if(parent->isAvatar())
05884                         {
05885                                 break;
05886                         }
05887                         object = parent;
05888                         parent = (LLViewerObject*)parent->getParent();
05889                 }
05890 
05891                 if (!object)
05892                 {
05893                         llwarns << "handle_detach() - no object to detach" << llendl;
05894                         return true;
05895                 }
05896 
05897                 if (object->isAvatar())
05898                 {
05899                         llwarns << "Trying to detach avatar from avatar." << llendl;
05900                         return true;
05901                 }
05902 
05903                 // The sendDetach() method works on the list of selected
05904                 // objects.  Thus we need to clear the list, make sure it only
05905                 // contains the object the user clicked, send the message,
05906                 // then clear the list.
05907                 // We use deselectAll to update the simulator's notion of what's
05908                 // selected, and removeAll just to change things locally.
05909                 //RN: I thought it was more useful to detach everything that was selected
05910                 if (gSelectMgr->getSelection()->isAttachment())
05911                 {
05912                         gSelectMgr->sendDetach();
05913                 }
05914                 return true;
05915         }
05916 };
05917 
05918 //Adding an observer for a Jira 2422 and needs to be a fetch observer
05919 //for Jira 3119
05920 class LLWornItemFetchedObserver : public LLInventoryFetchObserver
05921 {
05922 public:
05923         LLWornItemFetchedObserver() {}
05924         virtual ~LLWornItemFetchedObserver() {}
05925 
05926 protected:
05927         virtual void done()
05928         {
05929                 gPieAttachment->buildDrawLabels();
05930                 gInventory.removeObserver(this);
05931                 delete this;
05932         }
05933 };
05934 
05935 // You can only drop items on parcels where you can build.
05936 class LLAttachmentEnableDrop : public view_listener_t
05937 {
05938         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
05939         {
05940                 LLParcel* parcel = gParcelMgr->getAgentParcel();
05941                 BOOL can_build   = gAgent.isGodlike() || (parcel && parcel->getAllowModify());
05942 
05943                 //Add an inventory observer to only allow dropping the newly attached item
05944                 //once it exists in your inventory.  Look at Jira 2422.
05945                 //-jwolk
05946 
05947                 // A bug occurs when you wear/drop an item before it actively is added to your inventory
05948                 // if this is the case (you're on a slow sim, etc.) a copy of the object,
05949                 // well, a newly created object with the same properties, is placed
05950                 // in your inventory.  Therefore, we disable the drop option until the
05951                 // item is in your inventory
05952 
05953                 LLViewerObject*              object         = gViewerWindow->lastObjectHit();
05954                 LLViewerJointAttachment*     attachment_pt  = NULL;
05955                 LLInventoryItem*             item           = NULL;
05956 
05957                 if ( object )
05958                 {
05959                 S32 attachmentID  = ATTACHMENT_ID_FROM_STATE(object->getState());
05960                                 attachment_pt = gAgent.getAvatarObject()->mAttachmentPoints.getIfThere(attachmentID);
05961 
05962                         if ( attachment_pt )
05963                         {
05964                                 // make sure item is in your inventory (it could be a delayed attach message being sent from the sim)
05965                                 // so check to see if the item is in the inventory already
05966                                 item = gInventory.getItem(attachment_pt->getItemID());
05967                                 
05968                                 if ( !item )
05969                                 {
05970                                         // Item does not exist, make an observer to enable the pie menu 
05971                                         // when the item finishes fetching worst case scenario 
05972                                         // if a fetch is already out there (being sent from a slow sim)
05973                                         // we refetch and there are 2 fetches
05974                                         LLWornItemFetchedObserver* wornItemFetched = new LLWornItemFetchedObserver();
05975                                         LLInventoryFetchObserver::item_ref_t items; //add item to the inventory item to be fetched
05976 
05977                                         items.push_back(attachment_pt->getItemID());
05978                                 
05979                                         wornItemFetched->fetchItems(items);
05980                                         gInventory.addObserver(wornItemFetched);
05981                                 }
05982                         }
05983                 }
05984                 
05985                 //now check to make sure that the item is actually in the inventory before we enable dropping it
05986                 bool new_value = enable_detach(NULL) && can_build && item;
05987 
05988                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
05989                 return true;
05990         }
05991 };
05992 
05993 BOOL enable_detach(void*)
05994 {
05995         LLViewerObject* object = gViewerWindow->lastObjectHit();
05996         if (!object) return FALSE;
05997         if (!object->isAttachment()) return FALSE;
05998 
05999         // Find the avatar who owns this attachment
06000         LLViewerObject* avatar = object;
06001         while (avatar)
06002         {
06003                 // ...if it's you, good to detach
06004                 if (avatar->getID() == gAgent.getID())
06005                 {
06006                         return TRUE;
06007                 }
06008 
06009                 avatar = (LLViewerObject*)avatar->getParent();
06010         }
06011 
06012         return FALSE;
06013 }
06014 
06015 class LLAttachmentEnableDetach : public view_listener_t
06016 {
06017         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
06018         {
06019                 bool new_value = enable_detach(NULL);
06020                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
06021                 return true;
06022         }
06023 };
06024 
06025 // Used to tell if the selected object can be attached to your avatar.
06026 BOOL object_selected_and_point_valid(void *user_data)
06027 {
06028         //LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
06029         if (gSelectMgr == NULL)
06030         {
06031                 return FALSE;
06032         }
06033         LLObjectSelectionHandle selection = gSelectMgr->getSelection();
06034         for (LLObjectSelection::root_iterator iter = selection->root_begin();
06035                  iter != selection->root_end(); iter++)
06036         {
06037                 LLSelectNode* node = *iter;
06038                 LLViewerObject* object = node->getObject();
06039                 for (U32 child_num = 0; child_num < object->mChildList.size(); child_num++ )
06040                 {
06041                         if (object->mChildList[child_num]->isAvatar())
06042                         {
06043                                 return FALSE;
06044                         }
06045                 }
06046         }
06047 
06048         return (selection->getRootObjectCount() == 1) && 
06049                 (selection->getFirstRootObject()->getPCode() == LL_PCODE_VOLUME) && 
06050                 selection->getFirstRootObject()->permYouOwner() &&
06051                 !((LLViewerObject*)selection->getFirstRootObject()->getRoot())->isAvatar() && 
06052                 (selection->getFirstRootObject()->getNVPair("AssetContainer") == NULL);
06053 }
06054 
06055 // Also for seeing if object can be attached.  See above.
06056 class LLObjectEnableWear : public view_listener_t
06057 {
06058         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
06059         {
06060                 return object_selected_and_point_valid(NULL);
06061         }
06062 };
06063 
06064 
06065 BOOL object_attached(void *user_data)
06066 {
06067         LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
06068 
06069         return attachment->getObject() != NULL;
06070 }
06071 
06072 class LLAvatarSendIM : public view_listener_t
06073 {
06074         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
06075         {
06076                 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
06077                 if(avatar)
06078                 {
06079                         LLString name("IM");
06080                         LLNameValue *first = avatar->getNVPair("FirstName");
06081                         LLNameValue *last = avatar->getNVPair("LastName");
06082                         if (first && last)
06083                         {
06084                                 name.assign( first->getString() );
06085                                 name.append(" ");
06086                                 name.append( last->getString() );
06087                         }
06088 
06089                         gIMMgr->setFloaterOpen(TRUE);
06090                         //EInstantMessage type = have_agent_callingcard(gLastHitObjectID)
06091                         //      ? IM_SESSION_ADD : IM_SESSION_CARDLESS_START;
06092                         gIMMgr->addSession(name,
06093                                                                 IM_NOTHING_SPECIAL,
06094                                                                 avatar->getID());
06095                 }
06096                 return true;
06097         }
06098 };
06099 
06100 class LLAvatarTrustNetRate : public view_listener_t
06101 {
06102         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
06103         {
06104                 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
06105                 if(avatar)
06106                 {
06107                         LLFloaterTrustNetRate::show(avatar->getID());
06108                 }
06109 
06110                 return true;
06111         }
06112 };
06113 
06114 void handle_activate(void*)
06115 {
06116 }
06117 
06118 BOOL enable_activate(void*)
06119 {
06120         return FALSE;
06121 }
06122 
06123 namespace
06124 {
06125         struct QueueObjects : public LLSelectedObjectFunctor
06126         {
06127                 BOOL scripted;
06128                 BOOL modifiable;
06129                 LLFloaterScriptQueue* mQueue;
06130                 QueueObjects(LLFloaterScriptQueue* q) : mQueue(q), scripted(FALSE), modifiable(FALSE) {}
06131                 virtual bool apply(LLViewerObject* obj)
06132                 {
06133                         scripted = obj->flagScripted();
06134                         modifiable = obj->permModify();
06135 
06136                         if( scripted && modifiable )
06137                         {
06138                                 mQueue->addObject(obj->getID());
06139                                 return false;
06140                         }
06141                         else
06142                         {
06143                                 return true; // fail: stop applying
06144                         }
06145                 }
06146         };
06147 }
06148 
06149 void queue_actions(LLFloaterScriptQueue* q, const std::string& noscriptmsg, const std::string& nomodmsg)
06150 {
06151         // Apply until an object fails
06152         QueueObjects func(q);
06153         const bool firstonly = true;
06154         bool fail = gSelectMgr->getSelection()->applyToObjects(&func, firstonly);
06155         if(fail)
06156         {
06157                 if ( !func.scripted )
06158                 {
06159                         gViewerWindow->alertXml(noscriptmsg);
06160                 }
06161                 else if ( !func.modifiable )
06162                 {
06163                         gViewerWindow->alertXml(nomodmsg);
06164                 }
06165                 else
06166                 {
06167                         llerrs << "Bad logic." << llendl;
06168                 }
06169         }
06170         else
06171         {
06172                 if (!q->start())
06173                 {
06174                         llwarns << "Unexpected script compile failure." << llendl;
06175                 }
06176         }
06177 }
06178 
06179 class LLToolsSelectedScriptAction : public view_listener_t
06180 {
06181         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
06182         {
06183                 LLString action = userdata.asString();
06184                 LLFloaterScriptQueue* queue = NULL;
06185                 if (action == "compile")
06186                 {
06187                         queue = LLFloaterCompileQueue::create();
06188                 }
06189                 else if (action == "reset")
06190                 {
06191                         queue = LLFloaterResetQueue::create();
06192                 }
06193                 else if (action == "start")
06194                 {
06195                         queue = LLFloaterRunQueue::create();
06196                 }
06197                 else if (action == "stop")
06198                 {
06199                         queue = LLFloaterNotRunQueue::create();
06200                 }
06201                 if (!queue)
06202                 {
06203                         return true;
06204                 }
06205 
06206                 queue_actions(queue, "CannotRecompileSelectObjectsNoScripts", "CannotRecompileSelectObjectsNoPermission");
06207 
06208                 return true;
06209         }
06210 };
06211 
06212 void handle_reset_selection(void*)
06213 {
06214         LLFloaterResetQueue* queue = LLFloaterResetQueue::create();
06215         queue_actions(queue, "CannotResetSelectObjectsNoScripts", "CannotResetSelectObjectsNoPermission");
06216 }
06217 
06218 void handle_set_run_selection(void*)
06219 {
06220         LLFloaterRunQueue* queue = LLFloaterRunQueue::create();
06221         queue_actions(queue, "CannotSetRunningSelectObjectsNoScripts", "CannotSerRunningSelectObjectsNoPermission");
06222 }
06223 
06224 void handle_set_not_run_selection(void*)
06225 {
06226         LLFloaterNotRunQueue* queue = LLFloaterNotRunQueue::create();
06227         queue_actions(queue, "CannotSetRunningNotSelectObjectsNoScripts", "CannotSerRunningNotSelectObjectsNoPermission");
06228 }
06229 
06230 void handle_selected_texture_info(void*)
06231 {
06232         for (LLObjectSelection::valid_iterator iter = gSelectMgr->getSelection()->valid_begin();
06233                  iter != gSelectMgr->getSelection()->valid_end(); iter++)
06234         {
06235                 LLSelectNode* node = *iter;
06236                 
06237                 std::string msg;
06238                 msg.assign("Texture info for: ");
06239                 msg.append(node->mName);
06240                 LLChat chat(msg);
06241                 LLFloaterChat::addChat(chat);
06242 
06243                 U8 te_count = node->getObject()->getNumTEs();
06244                 // map from texture ID to list of faces using it
06245                 typedef std::map< LLUUID, std::vector<U8> > map_t;
06246                 map_t faces_per_texture;
06247                 for (U8 i = 0; i < te_count; i++)
06248                 {
06249                         if (!node->isTESelected(i)) continue;
06250 
06251                         LLViewerImage* img = node->getObject()->getTEImage(i);
06252                         LLUUID image_id = img->getID();
06253                         faces_per_texture[image_id].push_back(i);
06254                 }
06255                 // Per-texture, dump which faces are using it.
06256                 map_t::iterator it;
06257                 for (it = faces_per_texture.begin(); it != faces_per_texture.end(); ++it)
06258                 {
06259                         LLUUID image_id = it->first;
06260                         U8 te = it->second[0];
06261                         LLViewerImage* img = node->getObject()->getTEImage(te);
06262                         S32 height = img->getHeight();
06263                         S32 width = img->getWidth();
06264                         S32 components = img->getComponents();
06265                         std::string image_id_string;
06266                         if (gAgent.isGodlike())
06267                         {
06268                                 image_id_string = image_id.asString() + " ";
06269                         }
06270                         msg = llformat("%s%dx%d %s on face ",
06271                                                                 image_id_string.c_str(),
06272                                                                 width,
06273                                                                 height,
06274                                                                 (components == 4 ? "alpha" : "opaque"));
06275                         for (U8 i = 0; i < it->second.size(); ++i)
06276                         {
06277                                 msg.append( llformat("%d ", (S32)(it->second[i])));
06278                         }
06279                         LLChat chat(msg);
06280                         LLFloaterChat::addChat(chat);
06281                 }
06282         }
06283 }
06284 
06285 void handle_dump_image_list(void*)
06286 {
06287         gImageList.dump();
06288 }
06289 
06290 void handle_test_male(void*)
06291 {
06292         wear_outfit_by_name("Male Shape & Outfit");
06293         //gGestureList.requestResetFromServer( TRUE );
06294 }
06295 
06296 void handle_test_female(void*)
06297 {
06298         wear_outfit_by_name("Female Shape & Outfit");
06299         //gGestureList.requestResetFromServer( FALSE );
06300 }
06301 
06302 void handle_toggle_pg(void*)
06303 {
06304         gAgent.setTeen( !gAgent.isTeen() );
06305 
06306         LLFloaterWorldMap::reloadIcons(NULL);
06307 
06308         llinfos << "PG status set to " << (S32)gAgent.isTeen() << llendl;
06309 }
06310 
06311 void handle_dump_attachments(void*)
06312 {
06313         LLVOAvatar* avatar = gAgent.getAvatarObject();
06314         if( !avatar )
06315         {
06316                 llinfos << "NO AVATAR" << llendl;
06317                 return;
06318         }
06319 
06320         for( LLViewerJointAttachment* attachment = avatar->mAttachmentPoints.getFirstData();
06321                 attachment;
06322                 attachment = avatar->mAttachmentPoints.getNextData() )
06323         {
06324                 S32 key = avatar->mAttachmentPoints.getCurrentKeyWithoutIncrement();
06325                 BOOL visible = (attachment->getObject() != NULL &&
06326                                                 attachment->getObject()->mDrawable.notNull() && 
06327                                                 !attachment->getObject()->mDrawable->isRenderType(0));
06328                 LLVector3 pos;
06329                 if (visible) pos = attachment->getObject()->mDrawable->getPosition();
06330                 llinfos << "ATTACHMENT " << key << ": item_id=" << attachment->getItemID()
06331                                 << (attachment->getObject() ? " present " : " absent ")
06332                                 << (visible ? "visible " : "invisible ")
06333                                 <<  " at " << pos
06334                                 << " and " << (visible ? attachment->getObject()->getPosition() : LLVector3::zero)
06335                                 << llendl;
06336         }
06337 }
06338 
06339 //---------------------------------------------------------------------
06340 // Callbacks for enabling/disabling items
06341 //---------------------------------------------------------------------
06342 
06343 BOOL menu_ui_enabled(void *user_data)
06344 {
06345         BOOL high_res = gSavedSettings.getBOOL( "HighResSnapshot" );
06346         return !high_res;
06347 }
06348 
06349 // TomY TODO DEPRECATE & REMOVE
06350 void menu_toggle_control( void* user_data )
06351 {
06352         BOOL checked = gSavedSettings.getBOOL( static_cast<char*>(user_data) );
06353         if (LLString(static_cast<char*>(user_data)) == "HighResSnapshot" && !checked)
06354         {
06355                 // High Res Snapshot active, must uncheck RenderUIInSnapshot
06356                 gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE );
06357         }
06358         gSavedSettings.setBOOL( static_cast<char*>(user_data), !checked );
06359 }
06360 
06361 
06362 // these are used in the gl menus to set control values.
06363 class LLToggleControl : public view_listener_t
06364 {
06365         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
06366         {
06367                 LLString control_name = userdata.asString();
06368                 BOOL checked = gSavedSettings.getBOOL( control_name );
06369                 if (control_name == "HighResSnapshot" && !checked)
06370                 {
06371                         // High Res Snapshot active, must uncheck RenderUIInSnapshot
06372                         gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE );
06373                 }
06374                 gSavedSettings.setBOOL( control_name, !checked );
06375                 return true;
06376         }
06377 };
06378 
06379 // As above, but can be a callback from a LLCheckboxCtrl
06380 void check_toggle_control( LLUICtrl *, void* user_data )
06381 {
06382         BOOL checked = gSavedSettings.getBOOL( static_cast<char*>(user_data) );
06383         gSavedSettings.setBOOL( static_cast<char*>(user_data), !checked );
06384 }
06385 
06386 BOOL menu_check_control( void* user_data)
06387 {
06388         return gSavedSettings.getBOOL((char*)user_data);
06389 }
06390 
06391 // 
06392 void menu_toggle_variable( void* user_data )
06393 {
06394         BOOL checked = *(BOOL*)user_data;
06395         *(BOOL*)user_data = !checked;
06396 }
06397 
06398 BOOL menu_check_variable( void* user_data)
06399 {
06400         return *(BOOL*)user_data;
06401 }
06402 
06403 
06404 BOOL enable_land_selected( void* )
06405 {
06406         return gParcelMgr && !(gParcelMgr->selectionEmpty());
06407 }
06408 
06409 class LLSomethingSelected : public view_listener_t
06410 {
06411         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
06412         {
06413                 bool new_value = !(gSelectMgr->getSelection()->isEmpty());
06414                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
06415                 return true;
06416         }
06417 };
06418 
06419 class LLSomethingSelectedNoHUD : public view_listener_t
06420 {
06421         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
06422         {
06423                 LLObjectSelectionHandle selection = gSelectMgr->getSelection();
06424                 bool new_value = !(selection->isEmpty()) && !(selection->getSelectType() == SELECT_TYPE_HUD);
06425                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
06426                 return true;
06427         }
06428 };
06429 
06430 BOOL enable_more_than_one_selected(void* )
06431 {
06432         return (gSelectMgr->getSelection()->getObjectCount() > 1);
06433 }
06434 
06435 class LLEditableSelected : public view_listener_t
06436 {
06437         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
06438         {
06439                 bool new_value = (gSelectMgr->getSelection()->getFirstEditableObject() != NULL);
06440                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
06441                 return true;
06442         }
06443 };
06444 
06445 class LLToolsEnableTakeCopy : public view_listener_t
06446 {
06447         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
06448         {
06449                 bool all_valid = false;
06450                 if (gSelectMgr)
06451                 {
06452                         all_valid = true;
06453 #ifndef HACKED_GODLIKE_VIEWER
06454 # ifdef TOGGLE_HACKED_GODLIKE_VIEWER
06455                         if (gInProductionGrid || !gAgent.isGodlike())
06456 # endif
06457                         {
06458                                 struct f : public LLSelectedObjectFunctor
06459                                 {
06460                                         virtual bool apply(LLViewerObject* obj)
06461                                         {
06462                                                 return (!obj->permCopy() || obj->isAttachment());
06463                                         }
06464                                 } func;
06465                                 const bool firstonly = true;
06466                                 bool any_invalid = gSelectMgr->getSelection()->applyToRootObjects(&func, firstonly);
06467                                 all_valid = !any_invalid;
06468                         }
06469 #endif // HACKED_GODLIKE_VIEWER
06470                 }
06471 
06472                 gMenuHolder->findControl(userdata["control"].asString())->setValue(all_valid);
06473                 return true;
06474         }
06475 };
06476 
06477 BOOL enable_selection_you_own_all(void*)
06478 {
06479         if (gSelectMgr)
06480         {
06481                 struct f : public LLSelectedObjectFunctor
06482                 {
06483                         virtual bool apply(LLViewerObject* obj)
06484                         {
06485                                 return (!obj->permYouOwner());
06486                         }
06487                 } func;
06488                 const bool firstonly = true;
06489                 bool no_perms = gSelectMgr->getSelection()->applyToRootObjects(&func, firstonly);
06490                 if (no_perms)
06491                 {
06492                         return FALSE;
06493                 }
06494         }
06495         return TRUE;
06496 }
06497 
06498 BOOL enable_selection_you_own_one(void*)
06499 {
06500         if (gSelectMgr)
06501         {
06502                 struct f : public LLSelectedObjectFunctor
06503                 {
06504                         virtual bool apply(LLViewerObject* obj)
06505                         {
06506                                 return (obj->permYouOwner());
06507                         }
06508                 } func;
06509                 const bool firstonly = true;
06510                 bool any_perms = gSelectMgr->getSelection()->applyToRootObjects(&func, firstonly);
06511                 if (!any_perms)
06512                 {
06513                         return FALSE;
06514                 }
06515         }
06516         return TRUE;
06517 }
06518 
06519 class LLHasAsset : public LLInventoryCollectFunctor
06520 {
06521 public:
06522         LLHasAsset(const LLUUID& id) : mAssetID(id), mHasAsset(FALSE) {}
06523         virtual ~LLHasAsset() {}
06524         virtual bool operator()(LLInventoryCategory* cat,
06525                                                         LLInventoryItem* item);
06526         BOOL hasAsset() const { return mHasAsset; }
06527 
06528 protected:
06529         LLUUID mAssetID;
06530         BOOL mHasAsset;
06531 };
06532 
06533 bool LLHasAsset::operator()(LLInventoryCategory* cat,
06534                                                         LLInventoryItem* item)
06535 {
06536         if(item && item->getAssetUUID() == mAssetID)
06537         {
06538                 mHasAsset = TRUE;
06539         }
06540         return FALSE;
06541 }
06542 
06543 BOOL enable_save_into_inventory(void*)
06544 {
06545         if(gSelectMgr)
06546         {
06547                 // *TODO: clean this up
06548                 // find the last root
06549                 LLSelectNode* last_node = NULL;
06550                 for (LLObjectSelection::root_iterator iter = gSelectMgr->getSelection()->root_begin();
06551                          iter != gSelectMgr->getSelection()->root_end(); iter++)
06552                 {
06553                         last_node = *iter;
06554                 }
06555 
06556 #ifdef HACKED_GODLIKE_VIEWER
06557                 return TRUE;
06558 #else
06559 # ifdef TOGGLE_HACKED_GODLIKE_VIEWER
06560                 if (!gInProductionGrid && gAgent.isGodlike())
06561                 {
06562                         return TRUE;
06563                 }
06564 # endif
06565                 // check all pre-req's for save into inventory.
06566                 if(last_node && last_node->mValid && !last_node->mItemID.isNull()
06567                    && (last_node->mPermissions->getOwner() == gAgent.getID())
06568                    && (gInventory.getItem(last_node->mItemID) != NULL))
06569                 {
06570                         LLViewerObject* obj = last_node->getObject();
06571                         if( obj && !obj->isAttachment() )
06572                         {
06573                                 return TRUE;
06574                         }
06575                 }
06576 #endif
06577         }
06578         return FALSE;
06579 }
06580 
06581 class LLToolsEnableSaveToInventory : public view_listener_t
06582 {
06583         bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
06584         {
06585                 bool new_value = enable_save_into_inventory(NULL);
06586                 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
06587                 return true;
06588         }
06589 };
06590 
06591 BOOL enable_save_into_task_inventory(void*)
06592 {
06593         if(gSelectMgr)
06594         {
06595                 LLSelectNode* node = gSelectMgr->getSelection()->getFirstRootNode();
06596                 if(node && (node->mValid) && (!node->mFromTaskID.