aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llviewermenu.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:46 -0500
committerJacek Antonelli2008-08-15 23:44:46 -0500
commit38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch)
treeadca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llviewermenu.cpp
parentREADME.txt (diff)
downloadmeta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2
meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llviewermenu.cpp')
-rw-r--r--linden/indra/newview/llviewermenu.cpp8828
1 files changed, 8828 insertions, 0 deletions
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp
new file mode 100644
index 0000000..921e650
--- /dev/null
+++ b/linden/indra/newview/llviewermenu.cpp
@@ -0,0 +1,8828 @@
1/**
2 * @file llviewermenu.cpp
3 * @brief Builds menus out of items.
4 *
5 * Copyright (c) 2002-2007, Linden Research, Inc.
6 *
7 * The source code in this file ("Source Code") is provided by Linden Lab
8 * to you under the terms of the GNU General Public License, version 2.0
9 * ("GPL"), unless you have obtained a separate licensing agreement
10 * ("Other License"), formally executed by you and Linden Lab. Terms of
11 * the GPL can be found in doc/GPL-license.txt in this distribution, or
12 * online at http://secondlife.com/developers/opensource/gplv2
13 *
14 * There are special exceptions to the terms and conditions of the GPL as
15 * it is applied to this Source Code. View the full text of the exception
16 * in the file doc/FLOSS-exception.txt in this software distribution, or
17 * online at http://secondlife.com/developers/opensource/flossexception
18 *
19 * By copying, modifying or distributing this software, you acknowledge
20 * that you have read and understood your obligations described above,
21 * and agree to abide by those obligations.
22 *
23 * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
24 * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
25 * COMPLETENESS OR PERFORMANCE.
26 */
27
28#include "llviewerprecompiledheaders.h"
29
30#include "llviewermenu.h"
31
32// system library includes
33#include <iostream>
34#include <fstream>
35#include <sstream>
36#include <boost/tokenizer.hpp>
37
38// linden library includes
39#include "audioengine.h"
40#include "indra_constants.h"
41#include "llassetuploadresponders.h"
42#include "llassetstorage.h"
43#include "llchat.h"
44#include "lleconomy.h"
45#include "llfocusmgr.h"
46#include "llfontgl.h"
47#include "llinstantmessage.h"
48#include "llpermissionsflags.h"
49#include "llrect.h"
50#include "llsecondlifeurls.h"
51#include "lltransactiontypes.h"
52#include "llui.h"
53#include "llview.h"
54#include "llxfermanager.h"
55#include "message.h"
56#include "raytrace.h"
57#include "llsdserialize.h"
58#include "lltimer.h"
59#include "vorbisencode.h"
60#include "llvfile.h"
61#include "llvolumemgr.h"
62#include "llwindow.h" // for shell_open()
63
64// newview includes
65#include "llagent.h"
66#include "llagentpilot.h"
67#include "llbox.h"
68#include "llcallingcard.h"
69#include "llcameraview.h"
70#include "llclipboard.h"
71#include "llcompilequeue.h"
72#include "llconsole.h"
73#include "llviewercontrol.h"
74#include "lldebugview.h"
75#include "lldir.h"
76#include "lldrawable.h"
77#include "lldrawpoolalpha.h"
78#include "lldrawpoolhud.h"
79#include "lldrawpooltree.h"
80#include "llface.h"
81#include "llfirstuse.h"
82#include "llfloater.h"
83#include "llfloaterabout.h"
84#include "llfloaterbuycurrency.h"
85#include "llfloateranimpreview.h"
86#include "llfloateravatarinfo.h"
87#include "llfloateravatartextures.h"
88#include "llfloaterbuildoptions.h"
89#include "llfloaterbump.h"
90#include "llfloaterbuy.h"
91#include "llfloaterbuycontents.h"
92#include "llfloaterbuycurrency.h"
93#include "llfloaterbuyland.h"
94#include "llfloaterchat.h"
95#include "llfloatercustomize.h"
96#include "llfloaterdirectory.h"
97#include "llfloatereditui.h"
98#include "llfloaterfriends.h"
99#include "llfloatergesture.h"
100#include "llfloatergodtools.h"
101#include "llfloatergroupinfo.h"
102#include "llfloatergroups.h"
103#include "llfloaterhtmlhelp.h"
104#include "llfloaterhtmlfind.h"
105#include "llfloaterimport.h"
106#include "llfloaterinspect.h"
107#include "llfloaterland.h"
108#include "llfloaterlandholdings.h"
109#include "llfloatermap.h"
110#include "llfloateraccounthistory.h"
111#include "llfloaterimagepreview.h"
112#include "llfloatermute.h"
113#include "llfloaternamedesc.h"
114#include "llfloateropenobject.h"
115#include "llfloaterpermissionsmgr.h"
116#include "llfloaterpreference.h"
117#include "llfloaterrate.h"
118#include "llfloaterregioninfo.h"
119#include "llfloaterreporter.h"
120#include "llfloaterscriptdebug.h"
121#include "llfloatersnapshot.h"
122#include "llfloatertest.h"
123#include "llfloatertools.h"
124#include "llfloaterworldmap.h"
125#include "llframestats.h"
126#include "llframestatview.h"
127#include "llfasttimerview.h"
128#include "llmemoryview.h"
129#include "llgivemoney.h"
130#include "llgroupmgr.h"
131#include "llhoverview.h"
132#include "llhudeffecttrail.h"
133#include "llhudmanager.h"
134#include "llimage.h"
135#include "llimagebmp.h"
136#include "llimagej2c.h"
137#include "llimagetga.h"
138#include "llinventorymodel.h"
139#include "llinventoryview.h"
140#include "llkeyboard.h"
141#include "llpanellogin.h"
142#include "llmenucommands.h"
143#include "llmenugl.h"
144#include "llmorphview.h"
145#include "llmoveview.h"
146#include "llmutelist.h"
147#include "llnotify.h"
148#include "llpanelobject.h"
149#include "llparcel.h"
150#include "llpreviewscript.h"
151#include "llpreviewtexture.h"
152#include "llprimitive.h"
153#include "llresmgr.h"
154#include "llselectmgr.h"
155#include "llsky.h"
156#include "llstatusbar.h"
157#include "llstatview.h"
158#include "llstring.h"
159#include "llsurfacepatch.h"
160#include "llimview.h"
161#include "lltextureview.h"
162#include "lltool.h"
163#include "lltoolbar.h"
164#include "lltoolcomp.h"
165#include "lltoolfocus.h"
166#include "lltoolgrab.h"
167#include "lltoolmgr.h"
168#include "lltoolpie.h"
169#include "lltoolplacer.h"
170#include "lltoolselectland.h"
171#include "llvieweruictrlfactory.h"
172#include "lluploaddialog.h"
173#include "lluserauth.h"
174#include "lluuid.h"
175#include "llvelocitybar.h"
176#include "llviewercamera.h"
177#include "llviewergesture.h"
178#include "llviewerimagelist.h"
179#include "llviewerinventory.h"
180#include "llviewermessage.h"
181#include "llviewernetwork.h"
182#include "llviewerobjectlist.h"
183#include "llviewerparcelmgr.h"
184#include "llviewerparceloverlay.h"
185#include "llviewerregion.h"
186#include "llviewerstats.h"
187#include "llviewerwindow.h"
188#include "llvoavatar.h"
189#include "llvolume.h"
190#include "llweb.h"
191#include "llworld.h"
192#include "llworldmap.h"
193#include "object_flags.h"
194#include "pipeline.h"
195#include "viewer.h"
196#include "roles_constants.h"
197
198#include "lltexlayer.h"
199
200void init_client_menu(LLMenuGL* menu);
201void init_server_menu(LLMenuGL* menu);
202
203void init_debug_world_menu(LLMenuGL* menu);
204void init_debug_rendering_menu(LLMenuGL* menu);
205void init_debug_ui_menu(LLMenuGL* menu);
206void init_debug_xui_menu(LLMenuGL* menu);
207void init_debug_avatar_menu(LLMenuGL* menu);
208void init_debug_baked_texture_menu(LLMenuGL* menu);
209
210BOOL enable_land_build(void*);
211BOOL enable_object_build(void*);
212
213LLVOAvatar* find_avatar_from_object( LLViewerObject* object );
214LLVOAvatar* find_avatar_from_object( const LLUUID& object_id );
215
216void handle_test_load_url(void*);
217
218extern void disconnect_viewer(void *);
219
220//
221// Evil hackish imported globals
222//
223extern BOOL gRenderLightGlows;
224extern BOOL gRenderAvatar;
225extern BOOL gHideSelectedObjects;
226extern BOOL gShowOverlayTitle;
227extern BOOL gRandomizeFramerate;
228extern BOOL gPeriodicSlowFrame;
229extern BOOL gOcclusionCull;
230extern BOOL gAllowSelectAvatar;
231
232//
233// Globals
234//
235
236LLMenuBarGL *gMenuBarView = NULL;
237LLViewerMenuHolderGL *gMenuHolder = NULL;
238LLMenuGL *gPopupMenuView = NULL;
239
240// Pie menus
241LLPieMenu *gPieSelf = NULL;
242LLPieMenu *gPieAvatar = NULL;
243LLPieMenu *gPieObject = NULL;
244LLPieMenu *gPieAttachment = NULL;
245LLPieMenu *gPieLand = NULL;
246
247// local constants
248const LLString CLIENT_MENU_NAME("Client");
249const LLString SERVER_MENU_NAME("Server");
250
251const LLString SAVE_INTO_INVENTORY("Save Object Back to My Inventory");
252const LLString SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents");
253
254#if LL_WINDOWS
255static const char* SOUND_EXTENSIONS = ".wav";
256static const char* IMAGE_EXTENSIONS = ".tga .bmp .jpg .jpeg";
257static const char* ANIM_EXTENSIONS = ".bvh";
258#ifdef _CORY_TESTING
259static const char* GEOMETRY_EXTENSIONS = ".slg";
260#endif
261static const char* XML_EXTENSIONS = ".xml";
262static const char* SLOBJECT_EXTENSIONS = ".slobject";
263#endif
264static const char* ALL_FILE_EXTENSIONS = "*.*";
265
266LLMenuGL* gAttachSubMenu = NULL;
267LLMenuGL* gDetachSubMenu = NULL;
268LLMenuGL* gTakeOffClothes = NULL;
269LLPieMenu* gPieRate = NULL;
270LLPieMenu* gAttachScreenPieMenu = NULL;
271LLPieMenu* gAttachPieMenu = NULL;
272LLPieMenu* gAttachBodyPartPieMenus[8];
273LLPieMenu* gDetachPieMenu = NULL;
274LLPieMenu* gDetachScreenPieMenu = NULL;
275LLPieMenu* gDetachBodyPartPieMenus[8];
276
277LLMenuItemCallGL* gAFKMenu = NULL;
278LLMenuItemCallGL* gBusyMenu = NULL;
279
280typedef LLMemberListener<LLView> view_listener_t;
281
282//
283// Local prototypes
284//
285BOOL enable_attach(void*);
286void handle_leave_group(void *);
287
288// File Menu
289const char* upload_pick(void* data);
290void handle_upload(void* data);
291void handle_upload_object(void* data);
292void handle_compress_image(void*);
293BOOL enable_save_as(void *);
294
295// Edit menu
296void handle_dump_group_info(void *);
297void handle_dump_focus(void*);
298
299void handle_region_dump_settings(void*);
300void handle_region_dump_temp_asset_data(void*);
301void handle_region_clear_temp_asset_data(void*);
302
303// Object pie menu
304BOOL sitting_on_selection();
305
306void near_sit_object();
307void label_sit_or_stand(LLString& label, void*);
308// buy and take alias into the same UI positions, so these
309// declarations handle this mess.
310BOOL is_selection_buy_not_take();
311S32 selection_price();
312BOOL enable_take();
313void handle_take();
314void confirm_take(S32 option, void* data);
315BOOL enable_buy(void*);
316void handle_buy(void *);
317void handle_buy_object(LLSaleInfo sale_info);
318void handle_buy_contents(LLSaleInfo sale_info);
319void label_touch(LLString& label, void*);
320
321// Land pie menu
322void near_sit_down_point(BOOL success, void *);
323
324// Avatar pie menu
325void handle_follow(void *userdata);
326void handle_talk_to(void *userdata);
327
328// Debug menu
329void show_permissions_control(void*);
330void load_url_local_file(const char* file_name);
331void toggle_build_options(void* user_data);
332#if 0 // Unused
333void handle_audio_status_1(void*);
334void handle_audio_status_2(void*);
335void handle_audio_status_3(void*);
336void handle_audio_status_4(void*);
337#endif
338void reload_ui(void*);
339void handle_agent_stop_moving(void*);
340void print_packets_lost(void*);
341void drop_packet(void*);
342void velocity_interpolate( void* data );
343void update_fov(S32 increments);
344void toggle_wind_audio(void);
345void toggle_water_audio(void);
346void handle_rebake_textures(void*);
347BOOL check_admin_override(void*);
348void handle_admin_override_toggle(void*);
349#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
350void handle_toggle_hacked_godmode(void*);
351BOOL check_toggle_hacked_godmode(void*);
352#endif
353
354void toggle_glow(void *);
355BOOL check_glow(void *);
356
357void toggle_vbo(void *);
358BOOL check_vbo(void *);
359
360void toggle_vertex_shaders(void *);
361BOOL check_vertex_shaders(void *);
362
363void toggle_cull_small(void *);
364
365void toggle_show_xui_names(void *);
366BOOL check_show_xui_names(void *);
367
368// Debug UI
369void handle_save_to_xml(void*);
370void handle_load_from_xml(void*);
371
372void handle_god_mode(void*);
373
374// God menu
375void handle_leave_god_mode(void*);
376
377BOOL is_inventory_visible( void* user_data );
378void handle_reset_view();
379
380void disabled_duplicate(void*);
381void handle_duplicate_in_place(void*);
382void handle_repeat_duplicate(void*);
383
384void handle_export(void*);
385void handle_deed_object_to_group(void*);
386BOOL enable_deed_object_to_group(void*);
387void handle_object_owner_self(void*);
388void handle_object_owner_permissive(void*);
389void handle_object_lock(void*);
390void handle_object_asset_ids(void*);
391void force_take_copy(void*);
392#ifdef _CORY_TESTING
393void force_export_copy(void*);
394void force_import_geometry(void*);
395#endif
396
397void handle_force_parcel_owner_to_me(void*);
398void handle_force_parcel_to_content(void*);
399void handle_claim_public_land(void*);
400
401void handle_god_expunge_user(void*);
402
403void handle_god_request_havok(void *);
404void handle_god_request_avatar_geometry(void *); // Hack for easy testing of new avatar geometry
405void reload_personal_settings_overrides(void *);
406void force_breakpoint(void *);
407void reload_vertex_shader(void *);
408void flush_animations(void *);
409void slow_mo_animations(void *);
410void handle_disconnect_viewer(void *);
411
412void handle_stopall(void*);
413void handle_hinge(void*);
414void handle_ptop(void*);
415void handle_lptop(void*);
416void handle_wheel(void*);
417void handle_dehinge(void*);
418BOOL enable_dehinge(void*);
419void handle_force_delete(void*);
420void print_object_info(void*);
421void show_debug_menus();
422void toggle_debug_menus(void*);
423void toggle_map( void* user_data );
424void export_info_callback(LLAssetInfo *info, void **user_data, S32 result);
425void export_data_callback(LLVFS *vfs, const LLUUID& uuid, LLAssetType::EType type, void **user_data, S32 result);
426void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result);
427BOOL menu_check_build_tool( void* user_data );
428void handle_reload_settings(void*);
429void focus_here(void*);
430void dump_select_mgr(void*);
431void dump_volume_mgr(void*);
432void dump_inventory(void*);
433void edit_ui(void*);
434void toggle_visibility(void*);
435BOOL get_visibility(void*);
436
437// Avatar Pie menu
438void request_friendship(const LLUUID& agent_id);
439
440// Tools menu
441void handle_first_tool(void*);
442void handle_next_tool(void*);
443void handle_previous_tool(void*);
444void handle_force_unlock(void*);
445void handle_selected_texture_info(void*);
446void handle_dump_image_list(void*);
447
448void handle_fullscreen_debug(void*);
449void handle_crash(void*);
450void handle_dump_followcam(void*);
451void handle_viewer_enable_circuit_log(void*);
452void handle_viewer_disable_circuit_log(void*);
453void handle_viewer_enable_message_log(void*);
454void handle_viewer_disable_message_log(void*);
455void handle_send_postcard(void*);
456void handle_gestures_old(void*);
457void handle_focus(void *);
458BOOL enable_buy_land(void*);
459void handle_move(void*);
460void handle_show_inventory(void*);
461void handle_activate(void*);
462BOOL enable_activate(void*);
463
464// Help menu
465void handle_buy_currency(void*);
466
467void handle_test_male(void *);
468void handle_test_female(void *);
469void handle_toggle_pg(void*);
470void handle_dump_attachments(void *);
471void handle_show_overlay_title(void*);
472void handle_dump_avatar_local_textures(void*);
473void handle_debug_avatar_textures(void*);
474void handle_grab_texture(void*);
475BOOL enable_grab_texture(void*);
476
477BOOL menu_ui_enabled(void *user_data);
478void check_toggle_control( LLUICtrl *, void* user_data );
479BOOL menu_check_control( void* user_data);
480void menu_toggle_variable( void* user_data );
481BOOL menu_check_variable( void* user_data);
482BOOL enable_land_selected( void* );
483BOOL enable_more_than_one_selected(void* );
484BOOL enable_selection_you_own_all(void*);
485BOOL enable_selection_you_own_one(void*);
486BOOL enable_save_into_inventory(void*);
487BOOL enable_save_into_task_inventory(void*);
488BOOL enable_not_thirdperson(void*);
489BOOL enable_export_selected(void *);
490BOOL enable_have_card(void*);
491BOOL enable_detach(void*);
492BOOL enable_region_owner(void*);
493
494
495class LLMenuParcelObserver : public LLParcelObserver
496{
497public:
498 LLMenuParcelObserver();
499 ~LLMenuParcelObserver();
500 virtual void changed();
501};
502
503static LLMenuParcelObserver* gMenuParcelObserver = NULL;
504
505LLMenuParcelObserver::LLMenuParcelObserver()
506{
507 gParcelMgr->addObserver(this);
508}
509
510LLMenuParcelObserver::~LLMenuParcelObserver()
511{
512 gParcelMgr->removeObserver(this);
513}
514
515void LLMenuParcelObserver::changed()
516{
517 gMenuHolder->childSetEnabled("Land Buy Pass", LLPanelLandGeneral::enableBuyPass(NULL));
518
519 BOOL buyable = enable_buy_land(NULL);
520 gMenuHolder->childSetEnabled("Land Buy", buyable);
521 gMenuHolder->childSetEnabled("Buy Land...", buyable);
522}
523
524
525//-----------------------------------------------------------------------------
526// Menu Construction
527//-----------------------------------------------------------------------------
528
529// code required to calculate anything about the menus
530void pre_init_menus()
531{
532 // static information
533 LLColor4 color;
534 color = gColors.getColor( "MenuDefaultBgColor" );
535 LLMenuGL::setDefaultBackgroundColor( color );
536 color = gColors.getColor( "MenuItemEnabledColor" );
537 LLMenuItemGL::setEnabledColor( color );
538 color = gColors.getColor( "MenuItemDisabledColor" );
539 LLMenuItemGL::setDisabledColor( color );
540 color = gColors.getColor( "MenuItemHighlightBgColor" );
541 LLMenuItemGL::setHighlightBGColor( color );
542 color = gColors.getColor( "MenuItemHighlightFgColor" );
543 LLMenuItemGL::setHighlightFGColor( color );
544}
545
546void initialize_menu_actions();
547
548//-----------------------------------------------------------------------------
549// Initialize main menus
550//
551// HOW TO NAME MENUS:
552//
553// First Letter Of Each Word Is Capitalized, Even At Or And
554//
555// Items that lead to dialog boxes end in "..."
556//
557// Break up groups of more than 6 items with separators
558//-----------------------------------------------------------------------------
559void init_menus()
560{
561 S32 top = gViewerWindow->getRootView()->getRect().getHeight();
562 S32 width = gViewerWindow->getRootView()->getRect().getWidth();
563
564 //
565 // Main menu bar
566 //
567 gMenuHolder = new LLViewerMenuHolderGL();
568 gMenuHolder->setRect(LLRect(0, top - MENU_BAR_HEIGHT, width, STATUS_BAR_HEIGHT));
569 gMenuHolder->setFollowsAll();
570
571 LLMenuGL::sDefaultMenuContainer = gMenuHolder;
572
573 // Initialize actions
574 initialize_menu_actions();
575
576 gMenuBarView = (LLMenuBarGL*)gUICtrlFactory->buildMenu("menu_viewer.xml", gMenuHolder);
577 gMenuBarView->setRect(LLRect(0, top, width, top - MENU_BAR_HEIGHT));
578 gViewerWindow->getRootView()->addChild(gMenuBarView);
579
580 // menu holder appears on top of menu bar so you can see the menu title
581 // flash when an item is triggered (the flash occurs in the holder)
582 gViewerWindow->getRootView()->addChild(gMenuHolder);
583
584 gMenuHolder->childSetLabelArg("Upload Image", "[COST]", "10");
585 gMenuHolder->childSetLabelArg("Upload Sound", "[COST]", "10");
586 gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", "10");
587 gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", "10");
588
589 gAFKMenu = (LLMenuItemCallGL*)gMenuBarView->getChildByName("Set Away", TRUE);
590 gBusyMenu = (LLMenuItemCallGL*)gMenuBarView->getChildByName("Set Busy", TRUE);
591 gAttachSubMenu = gMenuBarView->getChildMenuByName("Attach Object", TRUE);
592 gDetachSubMenu = gMenuBarView->getChildMenuByName("Detach Object", TRUE);
593
594 if (gAgent.mAccess < SIM_ACCESS_MATURE)
595 {
596 gMenuBarView->getChildByName("Menu Underpants", TRUE)->setVisible(FALSE);
597 gMenuBarView->getChildByName("Menu Undershirt", TRUE)->setVisible(FALSE);
598 }
599
600 // TomY TODO convert these two
601 LLMenuGL*menu;
602 menu = new LLMenuGL(CLIENT_MENU_NAME);
603 init_client_menu(menu);
604 gMenuBarView->appendMenu( menu );
605 menu->updateParent(gMenuHolder);
606
607 menu = new LLMenuGL(SERVER_MENU_NAME);
608 init_server_menu(menu);
609 gMenuBarView->appendMenu( menu );
610 menu->updateParent(gMenuHolder);
611
612 gMenuBarView->createJumpKeys();
613
614 ///
615 /// Popup menu
616 ///
617 /// The popup menu is now populated by the show_context_menu()
618 /// method.
619
620 gPopupMenuView = new LLMenuGL( "Popup" );
621 gPopupMenuView->setVisible( FALSE );
622 gMenuHolder->addChild( gPopupMenuView );
623
624 ///
625 /// Pie menus
626 ///
627 gPieSelf = gUICtrlFactory->buildPieMenu("menu_pie_self.xml", gMenuHolder);
628
629 // TomY TODO: what shall we do about these?
630 gDetachScreenPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Detach HUD", true);
631 gDetachPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Detach", true);
632
633 if (gAgent.mAccess < SIM_ACCESS_MATURE)
634 {
635 gMenuHolder->getChildByName("Self Underpants", TRUE)->setVisible(FALSE);
636 gMenuHolder->getChildByName("Self Undershirt", TRUE)->setVisible(FALSE);
637 }
638
639 gPieAvatar = gUICtrlFactory->buildPieMenu("menu_pie_avatar.xml", gMenuHolder);
640
641 gPieObject = gUICtrlFactory->buildPieMenu("menu_pie_object.xml", gMenuHolder);
642
643 gAttachScreenPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Attach HUD", true);
644 gAttachPieMenu = (LLPieMenu*)gMenuHolder->getChildByName("Object Attach", true);
645 gPieRate = (LLPieMenu*)gMenuHolder->getChildByName("Rate Menu", true);
646
647 gPieAttachment = gUICtrlFactory->buildPieMenu("menu_pie_attachment.xml", gMenuHolder);
648
649 gPieLand = gUICtrlFactory->buildPieMenu("menu_pie_land.xml", gMenuHolder);
650
651 ///
652 /// set up the colors
653 ///
654 LLColor4 color;
655
656 // If we are not in production, use a different color to make it apparent.
657 if (gInProductionGrid)
658 {
659 color = gColors.getColor( "MenuBarBgColor" );
660 }
661 else
662 {
663 color = gColors.getColor( "MenuNonProductionBgColor" );
664 }
665
666 gMenuBarView->setBackgroundColor( color );
667
668 LLColor4 pie_color = gColors.getColor("PieMenuBgColor");
669 gPieSelf->setBackgroundColor( pie_color );
670 gPieAvatar->setBackgroundColor( pie_color );
671 gPieObject->setBackgroundColor( pie_color );
672 gPieAttachment->setBackgroundColor( pie_color );
673 gPieLand->setBackgroundColor( pie_color );
674
675 color = gColors.getColor( "MenuPopupBgColor" );
676 gPopupMenuView->setBackgroundColor( color );
677
678 // Let land based option enable when parcel changes
679 gMenuParcelObserver = new LLMenuParcelObserver();
680
681 //
682 // Debug menu visiblity
683 //
684 show_debug_menus();
685}
686
687void init_client_menu(LLMenuGL* menu)
688{
689 LLMenuGL* sub_menu = NULL;
690
691 //menu->append(new LLMenuItemCallGL("Permissions Control", &show_permissions_control));
692
693// this is now in the view menu so we don't need it here!
694 {
695 LLMenuGL* sub = new LLMenuGL("Consoles");
696 menu->appendMenu(sub);
697 sub->append(new LLMenuItemCheckGL("Frame Console",
698 &toggle_visibility,
699 NULL,
700 &get_visibility,
701 (void*)gDebugView->mFrameStatView,
702 '2', MASK_CONTROL|MASK_SHIFT ) );
703 sub->append(new LLMenuItemCheckGL("Texture Console",
704 &toggle_visibility,
705 NULL,
706 &get_visibility,
707 (void*)gTextureView,
708 '3', MASK_CONTROL|MASK_SHIFT ) );
709 LLView* debugview = gDebugView->mDebugConsolep;
710 sub->append(new LLMenuItemCheckGL("Debug Console",
711 &toggle_visibility,
712 NULL,
713 &get_visibility,
714 debugview,
715 '4', MASK_CONTROL|MASK_SHIFT ) );
716#if 0 // Unused
717 {
718 LLMenuGL* sub = new LLMenuGL("Audio");
719 menu->appendMenu(sub);
720
721 sub->append(new LLMenuItemCallGL("Global Pos",
722 &handle_audio_status_1, NULL, NULL ,'5', MASK_CONTROL|MASK_SHIFT) );
723 sub->append(new LLMenuItemCallGL("Cone",
724 &handle_audio_status_2, NULL, NULL ,'6', MASK_CONTROL|MASK_SHIFT) );
725 sub->append(new LLMenuItemCallGL("Local Pos",
726 &handle_audio_status_3, NULL, NULL ,'7', MASK_CONTROL|MASK_SHIFT) );
727 sub->append(new LLMenuItemCallGL("Duration",
728 &handle_audio_status_4, NULL, NULL ,'8', MASK_CONTROL|MASK_SHIFT) );
729 sub->createJumpKeys();
730 }
731#endif
732 sub->append(new LLMenuItemCheckGL("Fast Timers",
733 &toggle_visibility,
734 NULL,
735 &get_visibility,
736 (void*)gDebugView->mFastTimerView,
737 '9', MASK_CONTROL|MASK_SHIFT ) );
738 sub->append(new LLMenuItemCheckGL("Memory",
739 &toggle_visibility,
740 NULL,
741 &get_visibility,
742 (void*)gDebugView->mMemoryView,
743 '0', MASK_CONTROL|MASK_SHIFT ) );
744 sub->appendSeparator();
745 sub->append(new LLMenuItemCallGL("Region Info to Debug Console",
746 &handle_region_dump_settings, NULL));
747 sub->append(new LLMenuItemCallGL("Group Info to Debug Console",
748 &handle_dump_group_info, NULL, NULL));
749 sub->createJumpKeys();
750 }
751
752 // neither of these works particularly well at the moment
753 /*menu->append(new LLMenuItemCallGL( "Reload UI XML", &reload_ui,
754 NULL, NULL, 'R', MASK_ALT | MASK_CONTROL ) );*/
755 /*menu->append(new LLMenuItemCallGL("Reload settings/colors",
756 &handle_reload_settings, NULL, NULL));*/
757 menu->append(new LLMenuItemCallGL("Reload personal setting overrides",
758 &reload_personal_settings_overrides, NULL, NULL, KEY_F2, MASK_CONTROL|MASK_SHIFT));
759
760 sub_menu = new LLMenuGL("HUD Info");
761 {
762 sub_menu->append(new LLMenuItemCheckGL("Velocity",
763 &toggle_visibility,
764 NULL,
765 &get_visibility,
766 (void*)gVelocityBar));
767
768 sub_menu->append(new LLMenuItemToggleGL("Camera", &gDisplayCameraPos ) );
769 sub_menu->append(new LLMenuItemToggleGL("Wind", &gDisplayWindInfo) );
770 sub_menu->append(new LLMenuItemToggleGL("FOV", &gDisplayFOV ) );
771 sub_menu->createJumpKeys();
772 }
773 menu->appendMenu(sub_menu);
774
775 menu->appendSeparator();
776
777 menu->append(new LLMenuItemCheckGL( "High-res Snapshot",
778 &menu_toggle_control,
779 NULL,
780 &menu_check_control,
781 (void*)"HighResSnapshot"));
782
783 menu->append(new LLMenuItemToggleGL("Quiet Snapshots to Disk",
784 &gQuietSnapshot));
785
786 menu->append(new LLMenuItemCheckGL("Show Mouselook Crosshairs",
787 &menu_toggle_control,
788 NULL,
789 &menu_check_control,
790 (void*)"ShowCrosshairs"));
791
792 menu->append(new LLMenuItemCheckGL("Debug Permissions",
793 &menu_toggle_control,
794 NULL,
795 &menu_check_control,
796 (void*)"DebugPermissions"));
797
798
799
800#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
801 if (!gInProductionGrid)
802 {
803 menu->append(new LLMenuItemCheckGL("Hacked Godmode",
804 &handle_toggle_hacked_godmode,
805 NULL,
806 &check_toggle_hacked_godmode,
807 (void*)"HackedGodmode"));
808 }
809#endif
810
811 menu->append(new LLMenuItemCallGL("Clear Group Cache",
812 LLGroupMgr::debugClearAllGroups));
813 menu->appendSeparator();
814
815 sub_menu = new LLMenuGL("Rendering");
816 init_debug_rendering_menu(sub_menu);
817 menu->appendMenu(sub_menu);
818
819 sub_menu = new LLMenuGL("World");
820 init_debug_world_menu(sub_menu);
821 menu->appendMenu(sub_menu);
822
823 sub_menu = new LLMenuGL("UI");
824 init_debug_ui_menu(sub_menu);
825 menu->appendMenu(sub_menu);
826
827 sub_menu = new LLMenuGL("XUI");
828 init_debug_xui_menu(sub_menu);
829 menu->appendMenu(sub_menu);
830
831 sub_menu = new LLMenuGL("Character");
832 init_debug_avatar_menu(sub_menu);
833 menu->appendMenu(sub_menu);
834
835{
836 LLMenuGL* sub = NULL;
837 sub = new LLMenuGL("Network");
838
839 sub->append(new LLMenuItemCallGL("Enable Circuit Log",
840 &handle_viewer_enable_circuit_log, NULL));
841 sub->append(new LLMenuItemCallGL("Disable Circuit Log",
842 &handle_viewer_disable_circuit_log, NULL));
843 sub->append(new LLMenuItemCallGL("Enable Message Log",
844 &handle_viewer_enable_message_log, NULL));
845 sub->append(new LLMenuItemCallGL("Disable Message Log",
846 &handle_viewer_disable_message_log, NULL));
847
848 sub->appendSeparator();
849
850 sub->append(new LLMenuItemCheckGL("Velocity Interpolate Objects",
851 &velocity_interpolate,
852 NULL,
853 &menu_check_control,
854 (void*)"VelocityInterpolate"));
855 sub->append(new LLMenuItemCheckGL("Ping Interpolate Object Positions",
856 &menu_toggle_control,
857 NULL,
858 &menu_check_control,
859 (void*)"PingInterpolate"));
860
861 sub->appendSeparator();
862
863 sub->append(new LLMenuItemCallGL("Drop a Packet",
864 &drop_packet, NULL, NULL,
865 'L', MASK_ALT | MASK_CONTROL));
866
867 menu->appendMenu( sub );
868 sub->createJumpKeys();
869 }
870 {
871 LLMenuGL* sub = NULL;
872 sub = new LLMenuGL("Recorder");
873
874 sub->append(new LLMenuItemCheckGL("Full Session Logging", &menu_toggle_control, NULL, &menu_check_control, (void*)"StatsSessionTrackFrameStats"));
875
876 sub->append(new LLMenuItemCallGL("Start Logging", &LLFrameStats::startLogging, NULL));
877 sub->append(new LLMenuItemCallGL("Stop Logging", &LLFrameStats::stopLogging, NULL));
878 sub->append(new LLMenuItemCallGL("Log 10 Seconds", &LLFrameStats::timedLogging10, NULL));
879 sub->append(new LLMenuItemCallGL("Log 30 Seconds", &LLFrameStats::timedLogging30, NULL));
880 sub->append(new LLMenuItemCallGL("Log 60 Seconds", &LLFrameStats::timedLogging60, NULL));
881 sub->appendSeparator();
882 sub->append(new LLMenuItemCallGL("Start Playback", &LLAgentPilot::startPlayback, NULL));
883 sub->append(new LLMenuItemCallGL("Stop Playback", &LLAgentPilot::stopPlayback, NULL));
884 sub->append(new LLMenuItemToggleGL("Loop Playback", &LLAgentPilot::sLoop) );
885 sub->append(new LLMenuItemCallGL("Start Record", &LLAgentPilot::startRecord, NULL));
886 sub->append(new LLMenuItemCallGL("Stop Record", &LLAgentPilot::saveRecord, NULL));
887
888 menu->appendMenu( sub );
889 sub->createJumpKeys();
890 }
891
892 menu->appendSeparator();
893
894 menu->append(new LLMenuItemToggleGL("Show Updates",
895 &gShowObjectUpdates,
896 'U', MASK_ALT | MASK_SHIFT | MASK_CONTROL));
897
898 menu->appendSeparator();
899
900 menu->append(new LLMenuItemCallGL("Compress Image...",
901 &handle_compress_image, NULL, NULL));
902
903 menu->append(new LLMenuItemCheckGL("Limit Select Distance",
904 &menu_toggle_control,
905 NULL,
906 &menu_check_control,
907 (void*)"LimitSelectDistance"));
908
909 menu->append(new LLMenuItemToggleGL("Disable Camera Constraints",
910 &LLViewerCamera::sDisableCameraConstraints));
911
912 menu->appendSeparator();
913
914 menu->append(new LLMenuItemCheckGL( "Console Window",
915 &menu_toggle_control,
916 NULL,
917 &menu_check_control,
918 (void*)"ShowConsoleWindow"));
919
920#ifndef LL_RELEASE_FOR_DOWNLOAD
921 {
922 LLMenuGL* sub = NULL;
923 sub = new LLMenuGL("Debugging");
924 sub->append(new LLMenuItemCallGL("Force Breakpoint", &force_breakpoint, NULL, NULL, 'B', MASK_CONTROL | MASK_ALT));
925 sub->append(new LLMenuItemCallGL("LLError And Crash", &handle_crash));
926 sub->createJumpKeys();
927 menu->appendMenu(sub);
928 }
929#endif
930
931 // TomY Temporary menu item so we can test this floater
932 menu->append(new LLMenuItemCheckGL("Clothing...",
933 &handle_clothing,
934 NULL,
935 NULL,
936 NULL));
937
938 menu->append(new LLMenuItemCallGL("Debug Settings", LLFloaterSettingsDebug::show, NULL, NULL));
939 menu->append(new LLMenuItemCheckGL("View Admin Options", &handle_admin_override_toggle, NULL, &check_admin_override, NULL, 'V', MASK_CONTROL | MASK_ALT));
940 menu->createJumpKeys();
941}
942
943void init_debug_world_menu(LLMenuGL* menu)
944{
945 menu->append(new LLMenuItemCheckGL("Mouse Moves Sun",
946 &menu_toggle_control,
947 NULL,
948 &menu_check_control,
949 (void*)"MouseSun",
950 'M', MASK_CONTROL|MASK_ALT));
951 menu->append(new LLMenuItemCheckGL("Sim Sun Override",
952 &menu_toggle_control,
953 NULL,
954 &menu_check_control,
955 (void*)"SkyOverrideSimSunPosition"));
956 menu->append(new LLMenuItemCallGL("Dump Scripted Camera",
957 &handle_dump_followcam, NULL, NULL));
958 menu->append(new LLMenuItemCheckGL("Fixed Weather",
959 &menu_toggle_control,
960 NULL,
961 &menu_check_control,
962 (void*)"FixedWeather"));
963 menu->createJumpKeys();
964}
965
966
967void handle_export_menus_to_xml(void*)
968{
969 LLFilePicker& picker = LLFilePicker::instance();
970 if(!picker.getSaveFile(LLFilePicker::FFSAVE_XML))
971 {
972 llwarns << "No file" << llendl;
973 return;
974 }
975 const char* filename = picker.getFirstFile();
976
977 llofstream out(filename);
978 LLXMLNodePtr node = gMenuBarView->getXML();
979 node->writeToOstream(out);
980 out.close();
981}
982
983extern BOOL gDebugClicks;
984extern BOOL gDebugWindowProc;
985extern BOOL gDebugTextEditorTips;
986extern BOOL gDebugSelectMgr;
987
988void init_debug_ui_menu(LLMenuGL* menu)
989{
990 menu->append(new LLMenuItemCallGL("Editable UI", &edit_ui));
991 menu->append(new LLMenuItemToggleGL("Async Keystrokes", &gHandleKeysAsync));
992 menu->append(new LLMenuItemCallGL( "Dump SelectMgr", &dump_select_mgr));
993 menu->append(new LLMenuItemCallGL( "Dump Inventory", &dump_inventory));
994 menu->append(new LLMenuItemCallGL( "Dump Focus Holder", &handle_dump_focus, NULL, NULL, 'F', MASK_ALT | MASK_CONTROL));
995 menu->append(new LLMenuItemCallGL( "Dump VolumeMgr", &dump_volume_mgr, NULL, NULL));
996 menu->append(new LLMenuItemCallGL( "Print Selected Object Info", &print_object_info, NULL, NULL, 'P', MASK_CONTROL|MASK_SHIFT ));
997 menu->append(new LLMenuItemCallGL( "Print Agent Info", &print_agent_nvpairs, NULL, NULL, 'P', MASK_SHIFT ));
998 menu->append(new LLMenuItemCallGL( "Print Texture Memory Stats", &output_statistics, NULL, NULL, 'M', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
999 menu->append(new LLMenuItemCheckGL("Double-Click Auto-Pilot",
1000 menu_toggle_control, NULL, menu_check_control,
1001 (void*)"DoubleClickAutoPilot"));
1002 menu->appendSeparator();
1003// menu->append(new LLMenuItemCallGL( "Print Packets Lost", &print_packets_lost, NULL, NULL, 'L', MASK_SHIFT ));
1004 menu->append(new LLMenuItemToggleGL("Debug SelectMgr", &gDebugSelectMgr));
1005 menu->append(new LLMenuItemToggleGL("Debug Clicks", &gDebugClicks));
1006 menu->append(new LLMenuItemToggleGL("Debug Views", &LLView::sDebugRects));
1007 menu->append(new LLMenuItemToggleGL("Debug Mouse Events", &LLView::sDebugMouseHandling));
1008 menu->append(new LLMenuItemToggleGL("Debug Keys", &LLView::sDebugKeys));
1009 menu->append(new LLMenuItemToggleGL("Debug WindowProc", &gDebugWindowProc));
1010 menu->append(new LLMenuItemToggleGL("Debug Text Editor Tips", &gDebugTextEditorTips));
1011 menu->createJumpKeys();
1012}
1013
1014void init_debug_xui_menu(LLMenuGL* menu)
1015{
1016 menu->append(new LLMenuItemCallGL("Floater Test...", LLFloaterTest::show));
1017 menu->append(new LLMenuItemCallGL("Export Menus to XML...", handle_export_menus_to_xml));
1018 menu->append(new LLMenuItemCallGL("Edit UI...", LLFloaterEditUI::show));
1019 menu->append(new LLMenuItemCallGL("Load from XML...", handle_load_from_xml));
1020 menu->append(new LLMenuItemCallGL("Save to XML...", handle_save_to_xml));
1021 menu->append(new LLMenuItemCheckGL("Show XUI Names", toggle_show_xui_names, NULL, check_show_xui_names, NULL));
1022
1023 //menu->append(new LLMenuItemCallGL("Buy Currency...", handle_buy_currency));
1024 menu->createJumpKeys();
1025}
1026
1027void init_debug_rendering_menu(LLMenuGL* menu)
1028{
1029 LLMenuGL* sub_menu = NULL;
1030
1031 ///////////////////////////
1032 //
1033 // Debug menu for types/pools
1034 //
1035 sub_menu = new LLMenuGL("Types");
1036 menu->appendMenu(sub_menu);
1037
1038 sub_menu->append(new LLMenuItemCheckGL("Simple",
1039 &LLPipeline::toggleRenderType, NULL,
1040 &LLPipeline::toggleRenderTypeControl,
1041 (void*)LLPipeline::RENDER_TYPE_SIMPLE, '1', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
1042 sub_menu->append(new LLMenuItemCheckGL("Alpha",
1043 &LLPipeline::toggleRenderType, NULL,
1044 &LLPipeline::toggleRenderTypeControl,
1045 (void*)LLPipeline::RENDER_TYPE_ALPHA, '2', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
1046 sub_menu->append(new LLMenuItemCheckGL("Tree",
1047 &LLPipeline::toggleRenderType, NULL,
1048 &LLPipeline::toggleRenderTypeControl,
1049 (void*)LLPipeline::RENDER_TYPE_TREE, '3', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
1050 sub_menu->append(new LLMenuItemCheckGL("Character",
1051 &LLPipeline::toggleRenderType, NULL,
1052 &LLPipeline::toggleRenderTypeControl,
1053 (void*)LLPipeline::RENDER_TYPE_AVATAR, '4', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
1054 sub_menu->append(new LLMenuItemCheckGL("SurfacePatch",
1055 &LLPipeline::toggleRenderType, NULL,
1056 &LLPipeline::toggleRenderTypeControl,
1057 (void*)LLPipeline::RENDER_TYPE_TERRAIN, '5', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
1058 sub_menu->append(new LLMenuItemCheckGL("Sky",
1059 &LLPipeline::toggleRenderType, NULL,
1060 &LLPipeline::toggleRenderTypeControl,
1061 (void*)LLPipeline::RENDER_TYPE_SKY, '6', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
1062 sub_menu->append(new LLMenuItemCheckGL("Water",
1063 &LLPipeline::toggleRenderType, NULL,
1064 &LLPipeline::toggleRenderTypeControl,
1065 (void*)LLPipeline::RENDER_TYPE_WATER, '7', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
1066 sub_menu->append(new LLMenuItemCheckGL("Ground",
1067 &LLPipeline::toggleRenderType, NULL,
1068 &LLPipeline::toggleRenderTypeControl,
1069 (void*)LLPipeline::RENDER_TYPE_GROUND, '8', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
1070 sub_menu->append(new LLMenuItemCheckGL("Volume",
1071 &LLPipeline::toggleRenderType, NULL,
1072 &LLPipeline::toggleRenderTypeControl,
1073 (void*)LLPipeline::RENDER_TYPE_VOLUME, '9', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
1074 sub_menu->append(new LLMenuItemCheckGL("Grass",
1075 &LLPipeline::toggleRenderType, NULL,
1076 &LLPipeline::toggleRenderTypeControl,
1077 (void*)LLPipeline::RENDER_TYPE_GRASS, '0', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
1078 sub_menu->append(new LLMenuItemCheckGL("Clouds",
1079 &LLPipeline::toggleRenderType, NULL,
1080 &LLPipeline::toggleRenderTypeControl,
1081 (void*)LLPipeline::RENDER_TYPE_CLOUDS, '-', MASK_CONTROL|MASK_ALT| MASK_SHIFT));
1082 sub_menu->append(new LLMenuItemCheckGL("Particles",
1083 &LLPipeline::toggleRenderType, NULL,
1084 &LLPipeline::toggleRenderTypeControl,
1085 (void*)LLPipeline::RENDER_TYPE_PARTICLES, '=', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
1086 sub_menu->append(new LLMenuItemCheckGL("Bump",
1087 &LLPipeline::toggleRenderType, NULL,
1088 &LLPipeline::toggleRenderTypeControl,
1089 (void*)LLPipeline::RENDER_TYPE_BUMP, '\\', MASK_CONTROL|MASK_ALT|MASK_SHIFT));
1090 sub_menu->createJumpKeys();
1091 sub_menu = new LLMenuGL("Features");
1092 menu->appendMenu(sub_menu);
1093 sub_menu->append(new LLMenuItemCheckGL("UI",
1094 &LLPipeline::toggleRenderDebugFeature, NULL,
1095 &LLPipeline::toggleRenderDebugFeatureControl,
1096 (void*)LLPipeline::RENDER_DEBUG_FEATURE_UI, '1', MASK_ALT|MASK_CONTROL));
1097 sub_menu->append(new LLMenuItemCheckGL("Selected",
1098 &LLPipeline::toggleRenderDebugFeature, NULL,
1099 &LLPipeline::toggleRenderDebugFeatureControl,
1100 (void*)LLPipeline::RENDER_DEBUG_FEATURE_SELECTED, '2', MASK_ALT|MASK_CONTROL));
1101 sub_menu->append(new LLMenuItemCheckGL("Highlighted",
1102 &LLPipeline::toggleRenderDebugFeature, NULL,
1103 &LLPipeline::toggleRenderDebugFeatureControl,
1104 (void*)LLPipeline::RENDER_DEBUG_FEATURE_HIGHLIGHTED, '3', MASK_ALT|MASK_CONTROL));
1105 sub_menu->append(new LLMenuItemCheckGL("Dynamic Textures",
1106 &LLPipeline::toggleRenderDebugFeature, NULL,
1107 &LLPipeline::toggleRenderDebugFeatureControl,
1108 (void*)LLPipeline::RENDER_DEBUG_FEATURE_DYNAMIC_TEXTURES, '4', MASK_ALT|MASK_CONTROL));
1109 sub_menu->append(new LLMenuItemCheckGL("Fog",
1110 &LLPipeline::toggleRenderDebugFeature, NULL,
1111 &LLPipeline::toggleRenderDebugFeatureControl,
1112 (void*)LLPipeline::RENDER_DEBUG_FEATURE_FOG, '6', MASK_ALT|MASK_CONTROL));
1113 sub_menu->append(new LLMenuItemCheckGL("Palletized Textures",
1114 &LLPipeline::toggleRenderDebugFeature, NULL,
1115 &LLPipeline::toggleRenderDebugFeatureControl,
1116 (void*)LLPipeline::RENDER_DEBUG_FEATURE_PALETTE, '7', MASK_ALT|MASK_CONTROL));
1117 sub_menu->append(new LLMenuItemCheckGL("Test FRInfo",
1118 &LLPipeline::toggleRenderDebugFeature, NULL,
1119 &LLPipeline::toggleRenderDebugFeatureControl,
1120 (void*)LLPipeline::RENDER_DEBUG_FEATURE_FR_INFO, '8', MASK_ALT|MASK_CONTROL));
1121 sub_menu->append(new LLMenuItemCheckGL( "Flexible Objects",
1122 &LLPipeline::toggleRenderDebugFeature, NULL,
1123 &LLPipeline::toggleRenderDebugFeatureControl,
1124 (void*)LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE, '9', MASK_ALT|MASK_CONTROL));
1125 sub_menu->append(new LLMenuItemCheckGL( "Chain Faces",
1126 &LLPipeline::toggleRenderDebugFeature, NULL,
1127 &LLPipeline::toggleRenderDebugFeatureControl,
1128 (void*)LLPipeline::RENDER_DEBUG_FEATURE_CHAIN_FACES, '0', MASK_ALT|MASK_CONTROL));
1129 sub_menu->createJumpKeys();
1130
1131 /////////////////////////////
1132 //
1133 // Debug menu for info displays
1134 //
1135 sub_menu = new LLMenuGL("Info Displays");
1136 menu->appendMenu(sub_menu);
1137
1138 sub_menu->append(new LLMenuItemCheckGL("Verify", &LLPipeline::toggleRenderDebug, NULL,
1139 &LLPipeline::toggleRenderDebugControl,
1140 (void*)LLPipeline::RENDER_DEBUG_VERIFY));
1141 sub_menu->append(new LLMenuItemCheckGL("AGP Map", &LLPipeline::toggleRenderDebug, NULL,
1142 &LLPipeline::toggleRenderDebugControl,
1143 (void*)LLPipeline::RENDER_DEBUG_AGP_MEM));
1144 sub_menu->append(new LLMenuItemCheckGL("BBoxes", &LLPipeline::toggleRenderDebug, NULL,
1145 &LLPipeline::toggleRenderDebugControl,
1146 (void*)LLPipeline::RENDER_DEBUG_BBOXES));
1147 sub_menu->append(new LLMenuItemCheckGL("Points", &LLPipeline::toggleRenderDebug, NULL,
1148 &LLPipeline::toggleRenderDebugControl,
1149 (void*)LLPipeline::RENDER_DEBUG_POINTS));
1150 sub_menu->append(new LLMenuItemCheckGL("Octree", &LLPipeline::toggleRenderDebug, NULL,
1151 &LLPipeline::toggleRenderDebugControl,
1152 (void*)LLPipeline::RENDER_DEBUG_OCTREE));
1153 sub_menu->append(new LLMenuItemCheckGL("Occlusion", &LLPipeline::toggleRenderDebug, NULL,
1154 &LLPipeline::toggleRenderDebugControl,
1155 (void*)LLPipeline::RENDER_DEBUG_OCCLUSION));
1156 sub_menu->append(new LLMenuItemCheckGL("Face Chains", &LLPipeline::toggleRenderDebug, NULL,
1157 &LLPipeline::toggleRenderDebugControl,
1158 (void*)LLPipeline::RENDER_DEBUG_FACE_CHAINS));
1159 sub_menu->append(new LLMenuItemCheckGL("Texture Priority", &LLPipeline::toggleRenderDebug, NULL,
1160 &LLPipeline::toggleRenderDebugControl,
1161 (void*)LLPipeline::RENDER_DEBUG_TEXTURE_PRIORITY));
1162 sub_menu->append(new LLMenuItemCheckGL("Composition", &LLPipeline::toggleRenderDebug, NULL,
1163 &LLPipeline::toggleRenderDebugControl,
1164 (void*)LLPipeline::RENDER_DEBUG_COMPOSITION));
1165 sub_menu->append(new LLMenuItemCheckGL("ShadowMap", &LLPipeline::toggleRenderDebug, NULL,
1166 &LLPipeline::toggleRenderDebugControl,
1167 (void*)LLPipeline::RENDER_DEBUG_SHADOW_MAP));
1168 sub_menu->append(new LLMenuItemCheckGL("LightTrace",&LLPipeline::toggleRenderDebug, NULL,
1169 &LLPipeline::toggleRenderDebugControl,
1170 (void*)LLPipeline::RENDER_DEBUG_LIGHT_TRACE));
1171 sub_menu->append(new LLMenuItemCheckGL("Pools", &LLPipeline::toggleRenderDebug, NULL,
1172 &LLPipeline::toggleRenderDebugControl,
1173 (void*)LLPipeline::RENDER_DEBUG_POOLS));
1174 sub_menu->append(new LLMenuItemCheckGL("Queues", &LLPipeline::toggleRenderDebug, NULL,
1175 &LLPipeline::toggleRenderDebugControl,
1176 (void*)LLPipeline::RENDER_DEBUG_QUEUES));
1177 sub_menu->append(new LLMenuItemCheckGL("Map", &LLPipeline::toggleRenderDebug, NULL,
1178 LLPipeline::toggleRenderDebugControl,
1179 (void*)LLPipeline::RENDER_DEBUG_MAP));
1180
1181 sub_menu->append(new LLMenuItemCheckGL("Show Depth Buffer",
1182 &menu_toggle_control,
1183 NULL,
1184 &menu_check_control,
1185 (void*)"ShowDepthBuffer"));
1186 sub_menu->append(new LLMenuItemToggleGL("Show Select Buffer", &gDebugSelect));
1187
1188 sub_menu = new LLMenuGL("Render Tests");
1189
1190 sub_menu->append(new LLMenuItemCheckGL("Camera Offset",
1191 &menu_toggle_control,
1192 NULL,
1193 &menu_check_control,
1194 (void*)"CameraOffset"));
1195
1196 sub_menu->append(new LLMenuItemToggleGL("Randomize Framerate", &gRandomizeFramerate));
1197
1198 sub_menu->append(new LLMenuItemToggleGL("Periodic Slow Frame", &gPeriodicSlowFrame));
1199 sub_menu->createJumpKeys();
1200
1201 menu->appendMenu( sub_menu );
1202
1203 menu->appendSeparator();
1204 menu->append(new LLMenuItemCheckGL("Axes", menu_toggle_control, NULL, menu_check_control, (void*)"ShowAxes"));
1205 menu->append(new LLMenuItemCheckGL("Use VBO", toggle_vbo, NULL, check_vbo, NULL));
1206 menu->append(new LLMenuItemCheckGL("Light Glows", toggle_glow, NULL, check_glow, NULL));
1207// menu->append(new LLMenuItemCheckGL("Cull Small Objects", toggle_cull_small, NULL, menu_check_control, (void*)"RenderCullBySize"));
1208
1209 menu->appendSeparator();
1210 menu->append(new LLMenuItemToggleGL("Hide Selected", &gHideSelectedObjects));
1211 menu->appendSeparator();
1212 menu->append(new LLMenuItemCheckGL("Tangent Basis", menu_toggle_control, NULL, menu_check_control, (void*)"ShowTangentBasis"));
1213 menu->append(new LLMenuItemCallGL("Selected Texture Info", handle_selected_texture_info, NULL, NULL, 'T', MASK_CONTROL|MASK_SHIFT|MASK_ALT));
1214 //menu->append(new LLMenuItemCallGL("Dump Image List", handle_dump_image_list, NULL, NULL, 'I', MASK_CONTROL|MASK_SHIFT));
1215
1216 menu->append(new LLMenuItemToggleGL("Wireframe", &gUseWireframe,
1217 'R', MASK_CONTROL|MASK_SHIFT));
1218
1219 LLMenuItemCheckGL* item;
1220 item = new LLMenuItemCheckGL("Object-Object Occlusion", menu_toggle_control, NULL, menu_check_control, (void*)"UseOcclusion", 'O', MASK_CONTROL|MASK_SHIFT);
1221 item->setEnabled(gGLManager.mHasOcclusionQuery);
1222 menu->append(item);
1223
1224
1225 item = new LLMenuItemCheckGL("Animate Textures", menu_toggle_control, NULL, menu_check_control, (void*)"AnimateTextures");
1226 menu->append(item);
1227
1228 item = new LLMenuItemCheckGL("Disable Textures", menu_toggle_variable, NULL, menu_check_variable, (void*)&LLViewerImage::sDontLoadVolumeTextures);
1229 menu->append(item);
1230
1231 item = new LLMenuItemCheckGL("Cheesy Beacon", menu_toggle_control, NULL, menu_check_control, (void*)"CheesyBeacon");
1232 menu->append(item);
1233
1234#if 0 // 1.9.2
1235 item = new LLMenuItemCheckGL("Vertex Shaders", toggle_vertex_shaders, NULL, check_vertex_shaders, (void*)"VertexShaderEnable", 'V', MASK_CONTROL|MASK_ALT);
1236 item->setEnabled(gGLManager.mHasVertexShader);
1237 menu->append(item);
1238#endif
1239 menu->createJumpKeys();
1240}
1241
1242extern BOOL gDebugAvatarRotation;
1243
1244void init_debug_avatar_menu(LLMenuGL* menu)
1245{
1246 LLMenuGL* sub_menu = new LLMenuGL("Grab Baked Texture");
1247 init_debug_baked_texture_menu(sub_menu);
1248 menu->appendMenu(sub_menu);
1249
1250 sub_menu = new LLMenuGL("Character Tests");
1251 sub_menu->append(new LLMenuItemToggleGL("Go Away/AFK When Idle",
1252 &gAllowAFK));
1253
1254 sub_menu->append(new LLMenuItemCallGL("Appearance To XML",
1255 &LLVOAvatar::dumpArchetypeXML));
1256
1257 // HACK for easy testing of avatar geometry
1258 sub_menu->append(new LLMenuItemCallGL( "Toggle Character Geometry",
1259 &handle_god_request_avatar_geometry, &enable_god_customer_service, NULL));
1260
1261 sub_menu->append(new LLMenuItemCallGL("Test Male",
1262 handle_test_male));
1263
1264 sub_menu->append(new LLMenuItemCallGL("Test Female",
1265 handle_test_female));
1266
1267 sub_menu->append(new LLMenuItemCallGL("Toggle PG", handle_toggle_pg));
1268
1269 sub_menu->append(new LLMenuItemToggleGL("Allow Select Avatar", &gAllowSelectAvatar));
1270 sub_menu->createJumpKeys();
1271
1272 menu->appendMenu(sub_menu);
1273
1274 menu->append(new LLMenuItemCallGL("Force Params to Default", &LLAgent::clearVisualParams, NULL));
1275 menu->append(new LLMenuItemCallGL("Reload Vertex Shader", &reload_vertex_shader, NULL));
1276 menu->append(new LLMenuItemToggleGL("Animation Info", &LLVOAvatar::sShowAnimationDebug));
1277 menu->append(new LLMenuItemCallGL("Flush Animations", &flush_animations, NULL));
1278 menu->append(new LLMenuItemCallGL("Slow Motion Animations", &slow_mo_animations, NULL));
1279 menu->append(new LLMenuItemToggleGL("Show Look At", &LLHUDEffectLookAt::sDebugLookAt));
1280 menu->append(new LLMenuItemToggleGL("Show Point At", &LLHUDEffectPointAt::sDebugPointAt));
1281 menu->append(new LLMenuItemToggleGL("Debug Joint Updates", &LLVOAvatar::sJointDebug));
1282 menu->append(new LLMenuItemToggleGL("Disable LOD", &LLViewerJoint::sDisableLOD));
1283 menu->append(new LLMenuItemToggleGL("Debug Character Vis", &LLVOAvatar::sDebugInvisible));
1284 //menu->append(new LLMenuItemToggleGL("Show Attachment Points", &LLVOAvatar::sShowAttachmentPoints));
1285 menu->append(new LLMenuItemToggleGL("Show Collision Plane", &LLVOAvatar::sShowFootPlane));
1286 menu->append(new LLMenuItemToggleGL("Show Collision Skeleton", &LLVOAvatar::sShowCollisionVolumes));
1287 menu->append(new LLMenuItemToggleGL("Software Blending SSE", &gGLManager.mSoftwareBlendSSE));
1288#if 0 // Removed since this feature doesn't actually work as of 1.9.1 --TomY
1289 menu->append(new LLMenuItemToggleGL("Character Load Test", &LLVOAvatar::sAvatarLoadTest));
1290#endif
1291 menu->append(new LLMenuItemToggleGL( "Display Agent Target", &LLAgent::sDebugDisplayTarget));
1292 menu->append(new LLMenuItemToggleGL( "Debug Rotation", &gDebugAvatarRotation));
1293 menu->append(new LLMenuItemCallGL("Dump Attachments", handle_dump_attachments));
1294 menu->append(new LLMenuItemCallGL("Rebake Textures", handle_rebake_textures));
1295#ifndef LL_RELEASE_FOR_DOWNLOAD
1296 menu->append(new LLMenuItemCallGL("Debug Avatar Textures", handle_debug_avatar_textures, NULL, NULL, 'A', MASK_SHIFT|MASK_CONTROL|MASK_ALT));
1297 menu->append(new LLMenuItemCallGL("Dump Local Textures", handle_dump_avatar_local_textures, NULL, NULL, 'M', MASK_SHIFT|MASK_ALT ));
1298#endif
1299 menu->createJumpKeys();
1300}
1301
1302void init_debug_baked_texture_menu(LLMenuGL* menu)
1303{
1304 menu->append(new LLMenuItemCallGL("Iris", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_EYES_BAKED));
1305 menu->append(new LLMenuItemCallGL("Head", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_HEAD_BAKED));
1306 menu->append(new LLMenuItemCallGL("Upper Body", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_UPPER_BAKED));
1307 menu->append(new LLMenuItemCallGL("Lower Body", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_LOWER_BAKED));
1308 menu->append(new LLMenuItemCallGL("Skirt", handle_grab_texture, enable_grab_texture, (void*) LLVOAvatar::TEX_SKIRT_BAKED));
1309 menu->createJumpKeys();
1310}
1311
1312void init_server_menu(LLMenuGL* menu)
1313{
1314 /*
1315 {
1316 // These messages are now trusted. We can write scripts to do
1317 // this, and the message is unchecked for source.
1318 LLMenuGL* sub_menu = NULL;
1319 sub_menu = new LLMenuGL("Sim Logging");
1320
1321 sub_menu->append(new LLMenuItemCallGL("Turn off llinfos Log",
1322 &handle_reduce_llinfo_log, &enable_god_customer_service));
1323
1324 sub_menu->append(new LLMenuItemCallGL("Normal Logging",
1325 &handle_normal_llinfo_log, &enable_god_customer_service));
1326
1327 sub_menu->appendSeparator();
1328 sub_menu->append(new LLMenuItemCallGL("Enable Circuit Log",
1329 &handle_sim_enable_circuit_log, &enable_god_customer_service));
1330 sub_menu->append(new LLMenuItemCallGL("Disable Circuit Log",
1331 &handle_sim_disable_circuit_log, &enable_god_customer_service));
1332 sub_menu->appendSeparator();
1333 sub_menu->append(new LLMenuItemCallGL("Enable Message Log",
1334 &handle_sim_enable_message_log, &enable_god_customer_service));
1335 sub_menu->append(new LLMenuItemCallGL("Disable Message Log",
1336 &handle_sim_disable_message_log, &enable_god_customer_service));
1337
1338 sub_menu->appendSeparator();
1339
1340 sub_menu->append(new LLMenuItemCallGL("Fetch Message Log",
1341 &handle_sim_fetch_message_log, &enable_god_customer_service));
1342
1343 sub_menu->append(new LLMenuItemCallGL("Fetch Log",
1344 &handle_sim_fetch_log, &enable_god_customer_service));
1345
1346 menu->appendMenu( sub_menu );
1347 }
1348 */
1349
1350 {
1351 LLMenuGL* sub = new LLMenuGL("Object");
1352 menu->appendMenu(sub);
1353
1354 sub->append(new LLMenuItemCallGL( "Take Copy",
1355 &force_take_copy, &enable_god_customer_service, NULL));
1356#ifdef _CORY_TESTING
1357 sub->append(new LLMenuItemCallGL( "Export Copy",
1358 &force_export_copy, NULL, NULL));
1359 sub->append(new LLMenuItemCallGL( "Import Geometry",
1360 &force_import_geometry, NULL, NULL));
1361#endif
1362 //sub->append(new LLMenuItemCallGL( "Force Public",
1363 // &handle_object_owner_none, NULL, NULL));
1364 //sub->append(new LLMenuItemCallGL( "Force Ownership/Permissive",
1365 // &handle_object_owner_self_and_permissive, NULL, NULL, 'K', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
1366 sub->append(new LLMenuItemCallGL( "Force Owner To Me",
1367 &handle_object_owner_self, &enable_god_customer_service));
1368 sub->append(new LLMenuItemCallGL( "Force Owner Permissive",
1369 &handle_object_owner_permissive, &enable_god_customer_service));
1370 //sub->append(new LLMenuItemCallGL( "Force Totally Permissive",
1371 // &handle_object_permissive));
1372 sub->append(new LLMenuItemCallGL( "Delete",
1373 &handle_force_delete, &enable_god_customer_service, NULL, KEY_DELETE, MASK_SHIFT | MASK_ALT | MASK_CONTROL));
1374 sub->append(new LLMenuItemCallGL( "Lock",
1375 &handle_object_lock, &enable_god_customer_service, NULL, 'L', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
1376 sub->append(new LLMenuItemCallGL( "Get Asset IDs",
1377 &handle_object_asset_ids, &enable_god_customer_service, NULL, 'I', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
1378 sub->createJumpKeys();
1379 }
1380 {
1381 LLMenuGL* sub = new LLMenuGL("Parcel");
1382 menu->appendMenu(sub);
1383
1384 sub->append(new LLMenuItemCallGL("Owner To Me",
1385 &handle_force_parcel_owner_to_me,
1386 &enable_god_customer_service, NULL));
1387 sub->append(new LLMenuItemCallGL("Set to Linden Content",
1388 &handle_force_parcel_to_content,
1389 &enable_god_customer_service, NULL,
1390 'C', MASK_SHIFT | MASK_ALT | MASK_CONTROL));
1391 //sub->append(new LLMenuItemCallGL("Toggle First Land bit",
1392 // &handle_toggle_parcel_newbie));
1393 sub->appendSeparator();
1394 sub->append(new LLMenuItemCallGL("Claim Public Land",
1395 &handle_claim_public_land, &enable_god_customer_service));
1396
1397 sub->createJumpKeys();
1398 }
1399 {
1400 LLMenuGL* sub = new LLMenuGL("Region");
1401 menu->appendMenu(sub);
1402 sub->append(new LLMenuItemCallGL("Dump Temp Asset Data",
1403 &handle_region_dump_temp_asset_data,
1404 &enable_god_customer_service, NULL));
1405 sub->createJumpKeys();
1406 }
1407 menu->append(new LLMenuItemCallGL( "God Tools...",
1408 &LLFloaterGodTools::show, &enable_god_basic, NULL));
1409
1410 menu->appendSeparator();
1411
1412 menu->append(new LLMenuItemCallGL("Save Region State",
1413 &LLPanelRegionTools::onSaveState, &enable_god_customer_service, NULL));
1414
1415// menu->append(new LLMenuItemCallGL("Force Join Group", handle_force_join_group));
1416
1417
1418
1419 menu->appendSeparator();
1420//
1421// menu->append(new LLMenuItemCallGL( "OverlayTitle",
1422// &handle_show_overlay_title, &enable_god_customer_service, NULL));
1423
1424 menu->append(new LLMenuItemCallGL("Request Admin Status",
1425 &handle_god_mode, NULL, NULL, 'G', MASK_ALT | MASK_CONTROL));
1426
1427 menu->append(new LLMenuItemCallGL("Leave Admin Status",
1428 &handle_leave_god_mode, NULL, NULL, 'G', MASK_ALT | MASK_SHIFT | MASK_CONTROL));
1429 menu->createJumpKeys();
1430}
1431
1432//-----------------------------------------------------------------------------
1433// cleanup_menus()
1434//-----------------------------------------------------------------------------
1435void cleanup_menus()
1436{
1437 delete gMenuParcelObserver;
1438 gMenuParcelObserver = NULL;
1439}
1440
1441//-----------------------------------------------------------------------------
1442// Object pie menu
1443//-----------------------------------------------------------------------------
1444
1445class LLObjectRateCreator : public view_listener_t
1446{
1447 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1448 {
1449 LLFloaterRate::show(LLFloaterRate::RS_CREATOR);
1450 return true;
1451 }
1452};
1453
1454class LLObjectRateOwner : public view_listener_t
1455{
1456 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1457 {
1458 // Don't allow rating of group owned objects.
1459 LLSelectNode* node = gSelectMgr->getFirstRootNode();
1460 if (!node) return true;
1461 if (node->mPermissions->isGroupOwned())
1462 {
1463 gViewerWindow->alertXml("CantRateOwnedByGroup");
1464 return true;
1465 }
1466
1467 LLFloaterRate::show(LLFloaterRate::RS_OWNER);
1468 return true;
1469 }
1470};
1471
1472class LLObjectReportAbuse : public view_listener_t
1473{
1474 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1475 {
1476 LLFloaterReporter::showFromObject(gLastHitObjectID);
1477 return true;
1478 }
1479};
1480
1481// Enable only when you didn't create it, and the creator
1482// is not the owner.
1483class LLObjectEnableRateCreator : public view_listener_t
1484{
1485 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1486 {
1487 LLUUID creator_id;
1488 LLUUID owner_id;
1489 LLString dummy;
1490 BOOL identical_creator = gSelectMgr->selectGetCreator(creator_id, dummy);
1491
1492 BOOL new_value;
1493 if (!identical_creator)
1494 {
1495 new_value = FALSE;
1496 }
1497 else
1498 {
1499 new_value = (creator_id != gAgent.getID());
1500 }
1501 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
1502 return true;
1503 }
1504};
1505
1506// Enabled if object owner isn't the agent.
1507class LLObjectEnableRateOwner : public view_listener_t
1508{
1509 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1510 {
1511 LLUUID owner_id;
1512 LLString dummy;
1513 BOOL identical_owner = gSelectMgr->selectGetOwner(owner_id, dummy);
1514
1515 BOOL new_value;
1516 if (!identical_owner)
1517 {
1518 new_value = FALSE;
1519 }
1520 else if (owner_id.isNull())
1521 {
1522 new_value = FALSE;
1523 }
1524 else
1525 {
1526 new_value = (owner_id != gAgent.getID());
1527 }
1528 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
1529 return true;
1530 }
1531};
1532
1533
1534// Enabled it you clicked an object
1535class LLObjectEnableReportAbuse : public view_listener_t
1536{
1537 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1538 {
1539 bool new_value = !gLastHitObjectID.isNull();
1540 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
1541 return true;
1542 }
1543};
1544
1545
1546BOOL enable_attach(void*)
1547{
1548 // All root objects must be owned by agent.
1549 BOOL rv = FALSE;
1550 LLViewerObject* obj = gSelectMgr->getFirstRootObject();
1551 if(obj)
1552 {
1553 rv = TRUE;
1554 for(obj = gSelectMgr->getFirstRootObject() ; obj != NULL; obj = gSelectMgr->getNextRootObject())
1555 {
1556 for (U32 child_num = 0; child_num < obj->mChildList.size(); child_num++ )
1557 {
1558 LLViewerObject *child = obj->mChildList[child_num];
1559 if (child->isAvatar())
1560 {
1561 return FALSE;
1562 }
1563 }
1564 if(!obj->permMove())
1565 {
1566 rv = FALSE;
1567 break;
1568 }
1569 }
1570 }
1571 return rv;
1572}
1573
1574
1575class LLObjectTouch : public view_listener_t
1576{
1577 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1578 {
1579 LLViewerObject* object = gObjectList.findObject(gLastHitObjectID);
1580 if (!object) return true;
1581
1582 LLMessageSystem *msg = gMessageSystem;
1583
1584 msg->newMessageFast(_PREHASH_ObjectGrab);
1585 msg->nextBlockFast( _PREHASH_AgentData);
1586 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
1587 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
1588 msg->nextBlockFast( _PREHASH_ObjectData);
1589 msg->addU32Fast( _PREHASH_LocalID, object->mLocalID);
1590 msg->addVector3Fast(_PREHASH_GrabOffset, LLVector3::zero );
1591 msg->sendMessage( object->getRegion()->getHost());
1592
1593 // *NOTE: Hope the packets arrive safely and in order or else
1594 // there will be some problems.
1595 // *TODO: Just fix this bad assumption.
1596 msg->newMessageFast(_PREHASH_ObjectDeGrab);
1597 msg->nextBlockFast(_PREHASH_AgentData);
1598 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
1599 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
1600 msg->nextBlockFast(_PREHASH_ObjectData);
1601 msg->addU32Fast(_PREHASH_LocalID, object->mLocalID);
1602 msg->sendMessage(object->getRegion()->getHost());
1603
1604 gSelectMgr->deselectTransient();
1605 return true;
1606 }
1607};
1608
1609
1610// One object must have touch sensor
1611class LLObjectEnableTouch : public view_listener_t
1612{
1613 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1614 {
1615 LLViewerObject* obj = gObjectList.findObject(gLastHitObjectID);
1616 bool new_value = obj && obj->flagHandleTouch();
1617 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
1618
1619 // Update label based on the node touch name if available.
1620 LLSelectNode* node = gSelectMgr->getFirstRootNode();
1621 if (node && node->mValid && !node->mTouchName.empty())
1622 {
1623 gMenuHolder->childSetText("Object Touch", node->mTouchName);
1624 }
1625 else
1626 {
1627 gMenuHolder->childSetText("Object Touch", userdata["data"].asString());
1628 }
1629
1630 return true;
1631 }
1632};
1633
1634void label_touch(LLString& label, void*)
1635{
1636 LLSelectNode* node = gSelectMgr->getFirstRootNode();
1637 if (node && node->mValid && !node->mTouchName.empty())
1638 {
1639 label.assign(node->mTouchName);
1640 }
1641 else
1642 {
1643 label.assign("Touch");
1644 }
1645}
1646
1647bool handle_object_open()
1648{
1649 LLViewerObject* obj = gObjectList.findObject(gLastHitObjectID);
1650 if(!obj) return true;
1651
1652 // transient selection must be made permanent
1653 gSelectMgr->convertTransient();
1654 LLFloaterOpenObject::show();
1655 return true;
1656}
1657
1658class LLObjectOpen : public view_listener_t
1659{
1660 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1661 {
1662 return handle_object_open();
1663 }
1664};
1665
1666class LLObjectEnableOpen : public view_listener_t
1667{
1668 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1669 {
1670 // Look for contents in root object, which is all the LLFloaterOpenObject
1671 // understands.
1672 LLViewerObject* obj = gObjectList.findObject(gLastHitObjectID);
1673 bool new_value = (obj != NULL);
1674 if (new_value)
1675 {
1676 LLViewerObject* root = obj->getRootEdit();
1677 if (!root) new_value = false;
1678 else new_value = root->allowOpen();
1679 }
1680 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
1681 return true;
1682 }
1683};
1684
1685
1686class LLViewCheckBuildMode : public view_listener_t
1687{
1688 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1689 {
1690 bool new_value = gToolMgr->inEdit();
1691 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
1692 return true;
1693 }
1694};
1695
1696bool toggle_build_mode()
1697{
1698 if (gToolMgr->inEdit())
1699 {
1700 // just reset the view, will pull us out of edit mode
1701 handle_reset_view();
1702 }
1703 else
1704 {
1705 if (gAgent.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") )
1706 {
1707 // zoom in if we're looking at the avatar
1708 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
1709 gAgent.setFocusGlobal(gAgent.getPositionGlobal() + 2.0 * LLVector3d(gAgent.getAtAxis()));
1710 gAgent.cameraZoomIn(0.666f);
1711 gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
1712 }
1713
1714 gCurrentToolset = gBasicToolset;
1715 gCurrentToolset->selectTool( gToolCreate );
1716
1717 // Could be first use
1718 LLFirstUse::useBuild();
1719 }
1720 return true;
1721}
1722
1723class LLViewBuildMode : public view_listener_t
1724{
1725 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1726 {
1727 return toggle_build_mode();
1728 }
1729};
1730
1731
1732class LLObjectBuild : public view_listener_t
1733{
1734 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1735 {
1736 if (gAgent.getFocusOnAvatar() && !gToolMgr->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
1737 {
1738 // zoom in if we're looking at the avatar
1739 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
1740 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
1741 gAgent.cameraZoomIn(0.666f);
1742 gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
1743 gViewerWindow->moveCursorToCenter();
1744 }
1745 else if ( gSavedSettings.getBOOL("EditCameraMovement") )
1746 {
1747 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
1748 gViewerWindow->moveCursorToCenter();
1749 }
1750
1751 gCurrentToolset = gBasicToolset;
1752 gCurrentToolset->selectTool( gToolCreate );
1753
1754 // Could be first use
1755 LLFirstUse::useBuild();
1756 return true;
1757 }
1758};
1759
1760class LLObjectEdit : public view_listener_t
1761{
1762 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1763 {
1764 gParcelMgr->deselectLand();
1765 // convert transient selections to permanent
1766 gSelectMgr->convertTransient();
1767
1768 if (gAgent.getFocusOnAvatar() && !gToolMgr->inEdit())
1769 {
1770 if (gSelectMgr->getSelectType() == SELECT_TYPE_HUD || !gSavedSettings.getBOOL("EditCameraMovement"))
1771 {
1772 // always freeze camera in space, even if camera doesn't move
1773 // so, for example, follow cam scripts can't affect you when in build mode
1774 gAgent.setFocusGlobal(gAgent.calcFocusPositionTargetGlobal(), LLUUID::null);
1775 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
1776 }
1777 else
1778 {
1779 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
1780 // zoom in on object center instead of where we clicked, as we need to see the manipulator handles
1781 gAgent.setFocusGlobal(gLastHitPosGlobal /*+ gLastHitObjectOffset*/, gLastHitObjectID);
1782 gAgent.cameraZoomIn(0.666f);
1783 gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
1784 gViewerWindow->moveCursorToCenter();
1785 }
1786 }
1787
1788 gFloaterTools->open();
1789
1790 gCurrentToolset = gBasicToolset;
1791 gFloaterTools->setEditTool( gToolTranslate );
1792
1793 // Could be first use
1794 LLFirstUse::useBuild();
1795 return true;
1796 }
1797};
1798
1799class LLObjectInspect : public view_listener_t
1800{
1801 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1802 {
1803 gSelectMgr->convertTransient();
1804 LLFloaterInspect::show();
1805 return true;
1806 }
1807};
1808
1809
1810//---------------------------------------------------------------------------
1811// Land pie menu
1812//---------------------------------------------------------------------------
1813class LLLandBuild : public view_listener_t
1814{
1815 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1816 {
1817 gParcelMgr->deselectLand();
1818
1819 if (gAgent.getFocusOnAvatar() && !gToolMgr->inEdit() && gSavedSettings.getBOOL("EditCameraMovement") )
1820 {
1821 // zoom in if we're looking at the avatar
1822 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
1823 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
1824 gAgent.cameraZoomIn(0.666f);
1825 gAgent.cameraOrbitOver( 30.f * DEG_TO_RAD );
1826 gViewerWindow->moveCursorToCenter();
1827 }
1828 else if ( gSavedSettings.getBOOL("EditCameraMovement") )
1829 {
1830 // otherwise just move focus
1831 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
1832 gViewerWindow->moveCursorToCenter();
1833 }
1834
1835
1836 gCurrentToolset = gBasicToolset;
1837 gCurrentToolset->selectTool( gToolCreate );
1838
1839 // Could be first use
1840 LLFirstUse::useBuild();
1841 return true;
1842 }
1843};
1844
1845class LLLandBuyPass : public view_listener_t
1846{
1847 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1848 {
1849 LLPanelLandGeneral::onClickBuyPass((void *)FALSE);
1850 return true;
1851 }
1852};
1853
1854class LLLandEnableBuyPass : public view_listener_t
1855{
1856 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1857 {
1858 bool new_value = LLPanelLandGeneral::enableBuyPass(NULL);
1859 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
1860 return true;
1861 }
1862};
1863
1864// BUG: Should really check if CLICK POINT is in a parcel where you can build.
1865BOOL enable_land_build(void*)
1866{
1867 if (gAgent.isGodlike()) return TRUE;
1868 if (gAgent.inPrelude()) return FALSE;
1869
1870 BOOL can_build = FALSE;
1871 LLParcel* agent_parcel = gParcelMgr->getAgentParcel();
1872 if (agent_parcel)
1873 {
1874 can_build = agent_parcel->getAllowModify();
1875 }
1876 return can_build;
1877}
1878
1879// BUG: Should really check if OBJECT is in a parcel where you can build.
1880BOOL enable_object_build(void*)
1881{
1882 if (gAgent.isGodlike()) return TRUE;
1883 if (gAgent.inPrelude()) return FALSE;
1884
1885 BOOL can_build = FALSE;
1886 LLParcel* agent_parcel = gParcelMgr->getAgentParcel();
1887 if (agent_parcel)
1888 {
1889 can_build = agent_parcel->getAllowModify();
1890 }
1891 return can_build;
1892}
1893
1894class LLEnableEdit : public view_listener_t
1895{
1896 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1897 {
1898 bool new_value = gAgent.isGodlike() || !gAgent.inPrelude();
1899 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
1900 return true;
1901 }
1902};
1903
1904class LLSelfRemoveAllAttachments : public view_listener_t
1905{
1906 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1907 {
1908 LLAgent::userRemoveAllAttachments(NULL);
1909 return true;
1910 }
1911};
1912
1913class LLSelfEnableRemoveAllAttachments : public view_listener_t
1914{
1915 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1916 {
1917 bool new_value = false;
1918 if (gAgent.getAvatarObject())
1919 {
1920 LLVOAvatar* avatarp = gAgent.getAvatarObject();
1921 for (LLViewerJointAttachment* attachmentp = avatarp->mAttachmentPoints.getFirstData();
1922 attachmentp;
1923 attachmentp = avatarp->mAttachmentPoints.getNextData())
1924 {
1925 if (attachmentp->getObject(0))
1926 {
1927 new_value = true;
1928 break;
1929 }
1930 }
1931 }
1932 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
1933 return true;
1934 }
1935};
1936
1937BOOL enable_has_attachments(void*)
1938{
1939
1940 return FALSE;
1941}
1942
1943//---------------------------------------------------------------------------
1944// Avatar pie menu
1945//---------------------------------------------------------------------------
1946void handle_follow(void *userdata)
1947{
1948 // follow a given avatar, ID in gLastHitObjectID
1949 gAgent.startFollowPilot(gLastHitObjectID);
1950}
1951
1952class LLObjectEnableMute : public view_listener_t
1953{
1954 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1955 {
1956 LLViewerObject* object = gViewerWindow->lastObjectHit();
1957 bool new_value = (object != NULL);
1958 if (new_value)
1959 {
1960 LLVOAvatar* avatar = find_avatar_from_object(object);
1961 if (avatar)
1962 {
1963 // It's an avatar
1964 LLNameValue *lastname = avatar->getNVPair("LastName");
1965 BOOL is_linden = lastname && !LLString::compareStrings(lastname->getString(), "Linden");
1966 BOOL is_self = avatar->isSelf();
1967 new_value = !is_linden && !is_self;
1968 }
1969 }
1970 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
1971 return true;
1972 }
1973};
1974
1975class LLObjectMute : public view_listener_t
1976{
1977 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
1978 {
1979 LLViewerObject* object = gViewerWindow->lastObjectHit();
1980 if (!object) return true;
1981
1982 LLUUID id;
1983 LLString name;
1984 LLMute::EType type;
1985 LLVOAvatar* avatar = find_avatar_from_object(object);
1986 if (avatar)
1987 {
1988 id = avatar->getID();
1989
1990 LLNameValue *firstname = avatar->getNVPair("FirstName");
1991 LLNameValue *lastname = avatar->getNVPair("LastName");
1992 if (firstname && lastname)
1993 {
1994 name = firstname->getString();
1995 name += " ";
1996 name += lastname->getString();
1997 }
1998
1999 type = LLMute::AGENT;
2000 }
2001 else
2002 {
2003 // it's an object
2004 id = object->getID();
2005
2006 LLSelectNode* node = gSelectMgr->getFirstRootNode();
2007 if (node)
2008 {
2009 name = node->mName;
2010 }
2011
2012 type = LLMute::OBJECT;
2013 }
2014
2015 LLMute mute(id, name, type);
2016 if (gMuteListp->isMuted(mute.mID, mute.mName))
2017 {
2018 gMuteListp->remove(mute);
2019 }
2020 else
2021 {
2022 gMuteListp->add(mute);
2023 gFloaterMute->show();
2024 }
2025
2026 gSelectMgr->deselectAll();
2027 return true;
2028 }
2029};
2030
2031bool handle_go_to()
2032{
2033 // JAMESDEBUG try simulator autopilot
2034 std::vector<std::string> strings;
2035 std::string val;
2036 val = llformat("%g", gLastHitPosGlobal.mdV[VX]);
2037 strings.push_back(val);
2038 val = llformat("%g", gLastHitPosGlobal.mdV[VY]);
2039 strings.push_back(val);
2040 val = llformat("%g", gLastHitPosGlobal.mdV[VZ]);
2041 strings.push_back(val);
2042 send_generic_message("autopilot", strings);
2043
2044 // Don't select anything
2045 gSelectMgr->deselectTransient();
2046
2047 gParcelMgr->deselectLand();
2048
2049 if (gAgent.getAvatarObject() && !gSavedSettings.getBOOL("AutoPilotLocksCamera"))
2050 {
2051 gAgent.setFocusGlobal(gAgent.getFocusTargetGlobal(), gAgent.getAvatarObject()->getID());
2052 }
2053 else
2054 {
2055 // Snap camera back to behind avatar
2056 gAgent.setFocusOnAvatar(TRUE, ANIMATE);
2057 }
2058
2059 // Could be first use
2060 LLFirstUse::useGoTo();
2061 return true;
2062}
2063
2064class LLGoToObject : public view_listener_t
2065{
2066 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2067 {
2068 return handle_go_to();
2069 }
2070};
2071
2072//---------------------------------------------------------------------------
2073// Parcel freeze, eject, etc.
2074//---------------------------------------------------------------------------
2075void callback_freeze(S32 option, void* data)
2076{
2077 LLUUID* avatar_id = (LLUUID*) data;
2078
2079 if (0 == option || 1 == option)
2080 {
2081 U32 flags = 0x0;
2082 if (1 == option)
2083 {
2084 // unfreeze
2085 flags |= 0x1;
2086 }
2087
2088 LLMessageSystem* msg = gMessageSystem;
2089 LLViewerObject* avatar = gObjectList.findObject(*avatar_id);
2090
2091 if (avatar)
2092 {
2093 msg->newMessage("FreezeUser");
2094 msg->nextBlock("AgentData");
2095 msg->addUUID("AgentID", gAgent.getID());
2096 msg->addUUID("SessionID", gAgent.getSessionID());
2097 msg->nextBlock("Data");
2098 msg->addUUID("TargetID", *avatar_id );
2099 msg->addU32("Flags", flags );
2100 msg->sendReliable( avatar->getRegion()->getHost() );
2101 }
2102 }
2103
2104 delete avatar_id;
2105 avatar_id = NULL;
2106}
2107
2108class LLAvatarFreeze : public view_listener_t
2109{
2110 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2111 {
2112 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
2113 if( avatar )
2114 {
2115 LLUUID* avatar_id = new LLUUID( avatar->getID() );
2116
2117 gViewerWindow->alertXml("FreezeAvatar",
2118 callback_freeze, (void*)avatar_id);
2119
2120 }
2121 return true;
2122 }
2123};
2124
2125class LLAvatarVisibleDebug : public view_listener_t
2126{
2127 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2128 {
2129 bool new_value = gAgent.isGodlike();
2130 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
2131 return true;
2132 }
2133};
2134
2135class LLAvatarEnableDebug : public view_listener_t
2136{
2137 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2138 {
2139 bool new_value = gAgent.isGodlike();
2140 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
2141 return true;
2142 }
2143};
2144
2145class LLAvatarDebug : public view_listener_t
2146{
2147 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2148 {
2149 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
2150 if( avatar )
2151 {
2152 avatar->dumpLocalTextures();
2153 }
2154 llinfos << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << llendl;
2155 std::vector<std::string> strings;
2156 strings.push_back( avatar->getID().getString() );
2157 LLUUID invoice;
2158 send_generic_message("dumptempassetdata", strings, invoice);
2159 LLFloaterAvatarTextures::show( avatar->getID() );
2160 return true;
2161 }
2162};
2163
2164void callback_eject(S32 option, void* data)
2165{
2166 LLUUID* avatar_id = (LLUUID*) data;
2167
2168 if (0 == option || 1 == option)
2169 {
2170 LLMessageSystem* msg = gMessageSystem;
2171 LLViewerObject* avatar = gObjectList.findObject(*avatar_id);
2172
2173 if (avatar)
2174 {
2175 U32 flags = 0x0;
2176 if (1 == option)
2177 {
2178 // eject and add to ban list
2179 flags |= 0x1;
2180 }
2181
2182 msg->newMessage("EjectUser");
2183 msg->nextBlock("AgentData");
2184 msg->addUUID("AgentID", gAgent.getID() );
2185 msg->addUUID("SessionID", gAgent.getSessionID() );
2186 msg->nextBlock("Data");
2187 msg->addUUID("TargetID", *avatar_id );
2188 msg->addU32("Flags", flags );
2189 msg->sendReliable( avatar->getRegion()->getHost() );
2190 }
2191 }
2192
2193 delete avatar_id;
2194 avatar_id = NULL;
2195}
2196
2197class LLAvatarEject : public view_listener_t
2198{
2199 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2200 {
2201 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
2202 if( avatar )
2203 {
2204 LLUUID* avatar_id = new LLUUID( avatar->getID() );
2205 gViewerWindow->alertXml("EjectAvatar",
2206 callback_eject, (void*)avatar_id);
2207
2208 }
2209 return true;
2210 }
2211};
2212
2213class LLAvatarEnableFreezeEject : public view_listener_t
2214{
2215 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2216 {
2217 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
2218 bool new_value = (avatar != NULL);
2219
2220 if (new_value)
2221 {
2222 const LLVector3& pos = avatar->getPositionRegion();
2223 LLViewerRegion* region = avatar->getRegion();
2224 new_value = (region != NULL);
2225
2226 if (new_value)
2227 {
2228 new_value = (region->isOwnedSelf(pos) || region->isOwnedGroup(pos));
2229 }
2230 }
2231
2232 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
2233 return true;
2234 }
2235};
2236
2237class LLAvatarGiveCard : public view_listener_t
2238{
2239 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2240 {
2241 llinfos << "handle_give_card()" << llendl;
2242 LLViewerObject* dest = gViewerWindow->lastObjectHit();
2243 if(dest && dest->isAvatar())
2244 {
2245 bool found_name = false;
2246 LLString::format_map_t args;
2247 LLNameValue* nvfirst = dest->getNVPair("FirstName");
2248 LLNameValue* nvlast = dest->getNVPair("LastName");
2249 if(nvfirst && nvlast)
2250 {
2251 args["[FIRST]"] = nvfirst->getString();
2252 args["[LAST]"] = nvlast->getString();
2253 found_name = true;
2254 }
2255 LLViewerRegion* region = dest->getRegion();
2256 LLHost dest_host;
2257 if(region)
2258 {
2259 dest_host = region->getHost();
2260 }
2261 if(found_name && dest_host.isOk())
2262 {
2263 LLMessageSystem* msg = gMessageSystem;
2264 msg->newMessage("OfferCallingCard");
2265 msg->nextBlockFast(_PREHASH_AgentData);
2266 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2267 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2268 msg->nextBlockFast(_PREHASH_AgentBlock);
2269 msg->addUUIDFast(_PREHASH_DestID, dest->getID());
2270 LLUUID transaction_id;
2271 transaction_id.generate();
2272 msg->addUUIDFast(_PREHASH_TransactionID, transaction_id);
2273 msg->sendReliable(dest_host);
2274 LLNotifyBox::showXml("OfferedCard", args);
2275 }
2276 else
2277 {
2278 gViewerWindow->alertXml("CantOfferCallingCard", args);
2279 }
2280 }
2281 return true;
2282 }
2283};
2284
2285
2286
2287void login_done(S32 which, void *user)
2288{
2289 llinfos << "Login done " << which << llendl;
2290
2291 LLPanelLogin::close();
2292}
2293
2294
2295
2296class LLAvatarRate : public view_listener_t
2297{
2298 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2299 {
2300 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
2301 if( avatar )
2302 {
2303 LLFloaterRate::show( avatar->getID() );
2304 }
2305 return true;
2306 }
2307};
2308
2309void callback_leave_group(S32 option, void *userdata)
2310{
2311 if (option == 0)
2312 {
2313 LLMessageSystem *msg = gMessageSystem;
2314
2315 msg->newMessageFast(_PREHASH_LeaveGroupRequest);
2316 msg->nextBlockFast(_PREHASH_AgentData);
2317 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
2318 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2319 msg->nextBlockFast(_PREHASH_GroupData);
2320 msg->addUUIDFast(_PREHASH_GroupID, gAgent.mGroupID );
2321 //msg->sendReliable( gUserServer );
2322 gAgent.sendReliableMessage();
2323 }
2324}
2325
2326void handle_leave_group(void *)
2327{
2328 if (gAgent.getGroupID() != LLUUID::null)
2329 {
2330 LLString::format_map_t args;
2331 args["[GROUP]"] = gAgent.mGroupName;
2332 gViewerWindow->alertXml("GroupLeaveConfirmMember", args, callback_leave_group);
2333 }
2334}
2335
2336void append_aggregate(LLString& string, const LLAggregatePermissions& ag_perm, PermissionBit bit, const char* txt)
2337{
2338 LLAggregatePermissions::EValue val = ag_perm.getValue(bit);
2339 char buffer[MAX_STRING];
2340 buffer[0] = '\0';
2341 switch(val)
2342 {
2343 case LLAggregatePermissions::AP_NONE:
2344 sprintf(buffer, "* %s None\n", txt);
2345 break;
2346 case LLAggregatePermissions::AP_SOME:
2347 sprintf(buffer, "* %s Some\n", txt);
2348 break;
2349 case LLAggregatePermissions::AP_ALL:
2350 sprintf(buffer, "* %s All\n", txt);
2351 break;
2352 case LLAggregatePermissions::AP_EMPTY:
2353 default:
2354 break;
2355 }
2356 string.append(buffer);
2357}
2358
2359const char* build_extensions_string(LLFilePicker::ELoadFilter filter)
2360{
2361 switch(filter)
2362 {
2363#if LL_WINDOWS
2364 case LLFilePicker::FFLOAD_IMAGE:
2365 return IMAGE_EXTENSIONS;
2366 case LLFilePicker::FFLOAD_WAV:
2367 return SOUND_EXTENSIONS;
2368 case LLFilePicker::FFLOAD_ANIM:
2369 return ANIM_EXTENSIONS;
2370 case LLFilePicker::FFLOAD_SLOBJECT:
2371 return SLOBJECT_EXTENSIONS;
2372#ifdef _CORY_TESTING
2373 case LLFilePicker::FFLOAD_GEOMETRY:
2374 return GEOMETRY_EXTENSIONS;
2375#endif
2376 case LLFilePicker::FFLOAD_XML:
2377 return XML_EXTENSIONS;
2378 case LLFilePicker::FFLOAD_ALL:
2379 return ALL_FILE_EXTENSIONS;
2380#endif
2381 default:
2382 return ALL_FILE_EXTENSIONS;
2383 }
2384}
2385
2386
2387BOOL enable_buy(void*)
2388{
2389 // In order to buy, there must only be 1 purchaseable object in
2390 // the selection manger.
2391 if(gSelectMgr->getRootObjectCount() != 1) return FALSE;
2392 LLViewerObject* obj = NULL;
2393 LLSelectNode* node = gSelectMgr->getFirstRootNode();
2394 if(node)
2395 {
2396 obj = node->getObject();
2397 if(!obj) return FALSE;
2398
2399 if(node->mSaleInfo.isForSale() && node->mPermissions->getMaskOwner() & PERM_TRANSFER &&
2400 (node->mPermissions->getMaskOwner() & PERM_COPY || node->mSaleInfo.getSaleType() != LLSaleInfo::FS_COPY))
2401 {
2402 if(obj->permAnyOwner()) return TRUE;
2403 }
2404 }
2405 return FALSE;
2406}
2407
2408class LLObjectEnableBuy : public view_listener_t
2409{
2410 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2411 {
2412 bool new_value = enable_buy(NULL);
2413 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
2414 return true;
2415 }
2416};
2417
2418// Note: This will only work if the selected object's data has been
2419// received by the viewer and cached in the selection manager.
2420void handle_buy_object(LLSaleInfo sale_info)
2421{
2422 if(!gSelectMgr->selectGetAllRootsValid())
2423 {
2424 LLNotifyBox::showXml("UnableToBuyWhileDownloading");
2425 return;
2426 }
2427
2428 LLUUID owner_id;
2429 LLString owner_name;
2430 BOOL owners_identical = gSelectMgr->selectGetOwner(owner_id, owner_name);
2431 if (!owners_identical)
2432 {
2433 LLNotifyBox::showXml("CannotBuyObjectsFromDifferentOwners");
2434 return;
2435 }
2436
2437 LLPermissions perm;
2438 BOOL valid = gSelectMgr->selectGetPermissions(perm);
2439 LLAggregatePermissions ag_perm;
2440 valid &= gSelectMgr->selectGetAggregatePermissions(ag_perm);
2441 if(!valid || !sale_info.isForSale() || !perm.allowTransferTo(gAgent.getID()))
2442 {
2443 LLNotifyBox::showXml("ObjectNotForSale");
2444 return;
2445 }
2446
2447 if(sale_info.getSalePrice() > gStatusBar->getBalance())
2448 {
2449 LLFloaterBuyCurrency::buyCurrency(
2450 "This object costs", sale_info.getSalePrice());
2451 return;
2452 }
2453
2454 gSelectMgr->convertTransient();
2455 LLFloaterBuy::show(sale_info);
2456}
2457
2458
2459void handle_buy_contents(LLSaleInfo sale_info)
2460{
2461 gSelectMgr->convertTransient();
2462 LLFloaterBuyContents::show(sale_info);
2463}
2464
2465class LLFileEnableSaveAs : public view_listener_t
2466{
2467 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2468 {
2469 bool new_value = gFloaterView->getFrontmost() && gFloaterView->getFrontmost()->canSaveAs();
2470 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
2471 return true;
2472 }
2473};
2474
2475void handle_region_dump_temp_asset_data(void*)
2476{
2477 llinfos << "Dumping temporary asset data to simulator logs" << llendl;
2478 std::vector<std::string> strings;
2479 LLUUID invoice;
2480 send_generic_message("dumptempassetdata", strings, invoice);
2481}
2482
2483void handle_region_clear_temp_asset_data(void*)
2484{
2485 llinfos << "Clearing temporary asset data" << llendl;
2486 std::vector<std::string> strings;
2487 LLUUID invoice;
2488 send_generic_message("cleartempassetdata", strings, invoice);
2489}
2490
2491void handle_region_dump_settings(void*)
2492{
2493 LLViewerRegion* regionp = gAgent.getRegion();
2494 if (regionp)
2495 {
2496 llinfos << "Damage: " << (regionp->getAllowDamage() ? "on" : "off") << llendl;
2497 llinfos << "Landmark: " << (regionp->getAllowLandmark() ? "on" : "off") << llendl;
2498 llinfos << "SetHome: " << (regionp->getAllowSetHome() ? "on" : "off") << llendl;
2499 llinfos << "ResetHome: " << (regionp->getResetHomeOnTeleport() ? "on" : "off") << llendl;
2500 llinfos << "SunFixed: " << (regionp->getSunFixed() ? "on" : "off") << llendl;
2501 llinfos << "BlockFly: " << (regionp->getBlockFly() ? "on" : "off") << llendl;
2502 llinfos << "AllowP2P: " << (regionp->getAllowDirectTeleport() ? "on" : "off") << llendl;
2503 llinfos << "Water: " << (regionp->getWaterHeight()) << llendl;
2504 }
2505}
2506
2507void handle_dump_group_info(void *)
2508{
2509 llinfos << "group " << gAgent.mGroupName << llendl;
2510 llinfos << "ID " << gAgent.mGroupID << llendl;
2511 llinfos << "powers " << gAgent.mGroupPowers << llendl;
2512 llinfos << "title " << gAgent.mGroupTitle << llendl;
2513 //llinfos << "insig " << gAgent.mGroupInsigniaID << llendl;
2514}
2515
2516
2517void handle_dump_focus(void *)
2518{
2519 LLView *view = gFocusMgr.getKeyboardFocus();
2520
2521 llinfos << "Keyboard focus " << (view ? view->getName() : "(none)") << llendl;
2522}
2523
2524class LLSelfStandUp : public view_listener_t
2525{
2526 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2527 {
2528 gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
2529 return true;
2530 }
2531};
2532
2533class LLSelfEnableStandUp : public view_listener_t
2534{
2535 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2536 {
2537 bool new_value = gAgent.getAvatarObject() && gAgent.getAvatarObject()->mIsSitting;
2538 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
2539 return true;
2540 }
2541};
2542
2543BOOL check_admin_override(void*)
2544{
2545 return gAgent.getAdminOverride();
2546}
2547
2548void handle_admin_override_toggle(void*)
2549{
2550 if(!gAgent.getAdminOverride())
2551 {
2552 gAgent.setAdminOverride(TRUE);
2553 show_debug_menus();
2554 }
2555 else gAgent.setAdminOverride(FALSE);
2556}
2557
2558void handle_god_mode(void*)
2559{
2560 gAgent.requestEnterGodMode();
2561}
2562
2563void handle_leave_god_mode(void*)
2564{
2565 gAgent.requestLeaveGodMode();
2566}
2567
2568void set_god_level(U8 god_level)
2569{
2570 U8 old_god_level = gAgent.getGodLevel();
2571 gAgent.setGodLevel( god_level );
2572 show_debug_menus();
2573 gIMView->refresh();
2574 gParcelMgr->notifyObservers();
2575
2576 // Some classifieds change visibility on god mode
2577 LLFloaterDirectory::requestClassifieds();
2578
2579 // God mode changes sim visibility
2580 gWorldMap->reset();
2581 gWorldMap->setCurrentLayer(0);
2582
2583 // inventory in items may change in god mode
2584 gObjectList.dirtyAllObjectInventory();
2585
2586 LLString::format_map_t args;
2587 if(god_level > GOD_NOT)
2588 {
2589 args["[LEVEL]"] = llformat("%d",(S32)god_level);
2590 if (gInProductionGrid)
2591 {
2592 gMenuBarView->setBackgroundColor( gColors.getColor( "MenuBarGodBgColor" ) );
2593 }
2594 else
2595 {
2596 gMenuBarView->setBackgroundColor( gColors.getColor( "MenuNonProductionGodBgColor" ) );
2597 }
2598 LLNotifyBox::showXml("EnteringGodMode", args);
2599 }
2600 else
2601 {
2602 args["[LEVEL]"] = llformat("%d",(S32)old_god_level);
2603 if (gInProductionGrid)
2604 {
2605 gMenuBarView->setBackgroundColor( gColors.getColor( "MenuBarBgColor" ) );
2606 }
2607 else
2608 {
2609 gMenuBarView->setBackgroundColor( gColors.getColor( "MenuNonProductionBgColor" ) );
2610 }
2611 LLNotifyBox::showXml("LeavingGodMode", args);
2612 }
2613}
2614
2615#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
2616void handle_toggle_hacked_godmode(void*)
2617{
2618 gHackGodmode = !gHackGodmode;
2619 set_god_level(gHackGodmode ? GOD_MAINTENANCE : GOD_NOT);
2620}
2621
2622BOOL check_toggle_hacked_godmode(void*)
2623{
2624 return gHackGodmode;
2625}
2626#endif
2627
2628void process_grant_godlike_powers(LLMessageSystem* msg, void**)
2629{
2630 LLUUID agent_id;
2631 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
2632 LLUUID session_id;
2633 msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_SessionID, session_id);
2634 if((agent_id == gAgent.getID()) && (session_id == gAgent.getSessionID()))
2635 {
2636 U8 god_level;
2637 msg->getU8Fast(_PREHASH_GrantData, _PREHASH_GodLevel, god_level);
2638 set_god_level(god_level);
2639 }
2640 else
2641 {
2642 llwarns << "Grant godlike for wrong agent " << agent_id << llendl;
2643 }
2644}
2645
2646void load_url_local_file(const char* file_name)
2647{
2648 if( gAgent.cameraMouselook() )
2649 {
2650 gAgent.changeCameraToDefault();
2651 }
2652
2653#if LL_DARWIN || LL_LINUX
2654 // MBW -- If the Mac client is in fullscreen mode, it needs to go windowed so the browser will be visible.
2655 if(gViewerWindow->mWindow->getFullscreen())
2656 {
2657 gViewerWindow->toggleFullscreen(TRUE);
2658 }
2659#endif
2660
2661 // JC - system() blocks until IE has launched.
2662 // spawn() runs asynchronously, but opens a command prompt.
2663 // ShellExecute() just opens the damn file with the default
2664 // web browser.
2665 std::string full_path = "file:///";
2666 full_path.append(gDirUtilp->getAppRODataDir());
2667 full_path.append(gDirUtilp->getDirDelimiter());
2668 full_path.append(file_name);
2669
2670 LLWeb::loadURL(full_path.c_str());
2671}
2672
2673/*
2674class LLHaveCallingcard : public LLInventoryCollectFunctor
2675{
2676public:
2677 LLHaveCallingcard(const LLUUID& agent_id);
2678 virtual ~LLHaveCallingcard() {}
2679 virtual bool operator()(LLInventoryCategory* cat,
2680 LLInventoryItem* item);
2681 BOOL isThere() const { return mIsThere;}
2682protected:
2683 LLUUID mID;
2684 BOOL mIsThere;
2685};
2686
2687LLHaveCallingcard::LLHaveCallingcard(const LLUUID& agent_id) :
2688 mID(agent_id),
2689 mIsThere(FALSE)
2690{
2691}
2692
2693bool LLHaveCallingcard::operator()(LLInventoryCategory* cat,
2694 LLInventoryItem* item)
2695{
2696 if(item)
2697 {
2698 if((item->getType() == LLAssetType::AT_CALLINGCARD)
2699 && (item->getCreatorUUID() == mID))
2700 {
2701 mIsThere = TRUE;
2702 }
2703 }
2704 return FALSE;
2705}
2706*/
2707
2708BOOL is_agent_friend(const LLUUID& agent_id)
2709{
2710 return (LLAvatarTracker::instance().getBuddyInfo(agent_id) != NULL);
2711}
2712
2713BOOL is_agent_mappable(const LLUUID& agent_id)
2714{
2715 return (is_agent_friend(agent_id) &&
2716 LLAvatarTracker::instance().getBuddyInfo(agent_id)->isOnline() &&
2717 LLAvatarTracker::instance().getBuddyInfo(agent_id)->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)
2718 );
2719}
2720
2721// Enable a menu item when you have someone's card.
2722/*
2723BOOL enable_have_card(void *userdata)
2724{
2725 LLUUID* avatar_id = (LLUUID *)userdata;
2726 if (gAgent.isGodlike())
2727 {
2728 return TRUE;
2729 }
2730 else if(avatar_id)
2731 {
2732 return is_agent_friend(*avatar_id);
2733 }
2734 else
2735 {
2736 return FALSE;
2737 }
2738}
2739*/
2740
2741// Enable a menu item when you don't have someone's card.
2742class LLAvatarEnableAddFriend : public view_listener_t
2743{
2744 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2745 {
2746 LLVOAvatar* avatar = find_avatar_from_object(gViewerWindow->lastObjectHit());
2747 bool new_value = avatar && !is_agent_friend(avatar->getID());
2748 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
2749 return true;
2750 }
2751};
2752
2753void request_friendship(const LLUUID& dest_id)
2754{
2755 LLViewerObject* dest = gObjectList.findObject(dest_id);
2756 if(dest && dest->isAvatar())
2757 {
2758 LLString fullname;
2759 LLString::format_map_t args;
2760 LLNameValue* nvfirst = dest->getNVPair("FirstName");
2761 LLNameValue* nvlast = dest->getNVPair("LastName");
2762 if(nvfirst && nvlast)
2763 {
2764 args["[FIRST]"] = nvfirst->getString();
2765 args["[LAST]"] = nvlast->getString();
2766 fullname = nvfirst->getString();
2767 fullname += " ";
2768 fullname += nvlast->getString();
2769 }
2770 if (!fullname.empty())
2771 {
2772 LLFloaterFriends::requestFriendship(dest_id, fullname);
2773 LLNotifyBox::showXml("OfferedFriendship", args);
2774 }
2775 else
2776 {
2777 gViewerWindow->alertXml("CantOfferFriendship");
2778 }
2779 }
2780}
2781
2782
2783class LLEditEnableCustomizeAvatar : public view_listener_t
2784{
2785 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2786 {
2787 bool new_value = gAgent.getWearablesLoaded();
2788 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
2789 return true;
2790 }
2791};
2792
2793bool handle_sit_or_stand()
2794{
2795 LLViewerObject *object = gObjectList.findObject(gLastHitNonFloraObjectID);
2796 if (!object)
2797 {
2798 return true;
2799 }
2800
2801 if (sitting_on_selection())
2802 {
2803 gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
2804 gSelectMgr->deselectTransient();
2805 return true;
2806 }
2807
2808 // get object selection offset
2809
2810 if (object && object->getPCode() == LL_PCODE_VOLUME)
2811 {
2812 LLVector3d offset_double = gViewerWindow->lastNonFloraObjectHitOffset();
2813 LLVector3 offset_single;
2814 offset_single.setVec(offset_double);
2815
2816 gMessageSystem->newMessageFast(_PREHASH_AgentRequestSit);
2817 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
2818 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2819 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2820 gMessageSystem->nextBlockFast(_PREHASH_TargetObject);
2821 gMessageSystem->addUUIDFast(_PREHASH_TargetID, object->mID);
2822 gMessageSystem->addVector3Fast(_PREHASH_Offset, offset_single);
2823
2824 object->getRegion()->sendReliableMessage();
2825
2826 gSelectMgr->deselectTransient();
2827 }
2828 return true;
2829}
2830
2831class LLObjectSitOrStand : public view_listener_t
2832{
2833 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2834 {
2835 return handle_sit_or_stand();
2836 }
2837};
2838
2839void near_sit_down_point(BOOL success, void *)
2840{
2841 gAgent.setFlying(FALSE);
2842 gAgent.setControlFlags(AGENT_CONTROL_SIT_ON_GROUND);
2843
2844 // Might be first sit
2845 LLFirstUse::useSit();
2846}
2847
2848class LLLandSit : public view_listener_t
2849{
2850 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2851 {
2852 gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
2853 gParcelMgr->deselectLand();
2854
2855 LLVector3d posGlobal = gLastHitPosGlobal;
2856
2857 LLQuaternion target_rot;
2858 if (gAgent.getAvatarObject())
2859 {
2860 target_rot = gAgent.getAvatarObject()->getRotation();
2861 }
2862 else
2863 {
2864 target_rot = gAgent.getFrameAgent().getQuaternion();
2865 }
2866 gAgent.startAutoPilotGlobal(posGlobal, "Sit", &target_rot, near_sit_down_point, NULL, 0.7f);
2867 return true;
2868 }
2869};
2870
2871void show_permissions_control(void*)
2872{
2873 LLFloaterPermissionsMgr* floaterp = LLFloaterPermissionsMgr::show();
2874 floaterp->mPermissions->addPermissionsData("foo1", LLUUID::null, 0);
2875 floaterp->mPermissions->addPermissionsData("foo2", LLUUID::null, 0);
2876 floaterp->mPermissions->addPermissionsData("foo3", LLUUID::null, 0);
2877}
2878
2879#if 0 // Unused (these just modify AudioInfoPage which is not used anywhere in the code
2880void handle_audio_status_1(void*)
2881{
2882 S32 page = gSavedSettings.getS32("AudioInfoPage");
2883 if (1 == page)
2884 {
2885 page = 0;
2886 }
2887 else
2888 {
2889 page = 1;
2890 }
2891 gSavedSettings.setS32("AudioInfoPage", page);
2892}
2893
2894void handle_audio_status_2(void*)
2895{
2896 S32 page = gSavedSettings.getS32("AudioInfoPage");
2897 if (2 == page)
2898 {
2899 page = 0;
2900 }
2901 else
2902 {
2903 page = 2;
2904 }
2905 gSavedSettings.setS32("AudioInfoPage", page);
2906}
2907
2908void handle_audio_status_3(void*)
2909{
2910 S32 page = gSavedSettings.getS32("AudioInfoPage");
2911 if (3 == page)
2912 {
2913 page = 0;
2914 }
2915 else
2916 {
2917 page = 3;
2918 }
2919 gSavedSettings.setS32("AudioInfoPage", page);
2920}
2921
2922void handle_audio_status_4(void*)
2923{
2924 S32 page = gSavedSettings.getS32("AudioInfoPage");
2925 if (4 == page)
2926 {
2927 page = 0;
2928 }
2929 else
2930 {
2931 page = 4;
2932 }
2933 gSavedSettings.setS32("AudioInfoPage", page);
2934}
2935#endif
2936
2937void reload_ui(void *)
2938{
2939 gUICtrlFactory->rebuild();
2940}
2941
2942class LLWorldFly : public view_listener_t
2943{
2944 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2945 {
2946 gAgent.toggleFlying();
2947 return true;
2948 }
2949};
2950
2951void handle_agent_stop_moving(void*)
2952{
2953 // stop agent
2954 gAgent.setControlFlags(AGENT_CONTROL_STOP);
2955
2956 // cancel autopilot
2957 gAgent.stopAutoPilot();
2958}
2959
2960void print_packets_lost(void*)
2961{
2962 gWorldPointer->printPacketsLost();
2963}
2964
2965
2966void drop_packet(void*)
2967{
2968 gMessageSystem->mPacketRing.dropPackets(1);
2969}
2970
2971
2972void velocity_interpolate( void* data )
2973{
2974 BOOL toggle = gSavedSettings.getBOOL("VelocityInterpolate");
2975 LLMessageSystem* msg = gMessageSystem;
2976 if ( !toggle )
2977 {
2978 msg->newMessageFast(_PREHASH_VelocityInterpolateOn);
2979 msg->nextBlockFast(_PREHASH_AgentData);
2980 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2981 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2982 gAgent.sendReliableMessage();
2983 llinfos << "Velocity Interpolation On" << llendl;
2984 }
2985 else
2986 {
2987 msg->newMessageFast(_PREHASH_VelocityInterpolateOff);
2988 msg->nextBlockFast(_PREHASH_AgentData);
2989 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
2990 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
2991 gAgent.sendReliableMessage();
2992 llinfos << "Velocity Interpolation Off" << llendl;
2993 }
2994 // BUG this is a hack because of the change in menu behavior. The
2995 // old menu system would automatically change a control's value,
2996 // but the new LLMenuGL system doesn't know what a control
2997 // is. However, it's easy to distinguish between the two callers
2998 // because LLMenuGL passes in the name of the user data (the
2999 // control name) to the callback function, and the user data goes
3000 // unused in the old menu code. Thus, if data is not null, then we
3001 // need to swap the value of the control.
3002 if( data )
3003 {
3004 gSavedSettings.setBOOL( static_cast<char*>(data), !toggle );
3005 }
3006}
3007
3008
3009void update_fov(S32 increments)
3010{
3011 F32 old_fov = gCamera->getDefaultFOV();
3012 // for each increment, FoV is 20% bigger
3013 F32 new_fov = old_fov * pow(1.2f, increments);
3014
3015 // cap the FoV
3016 new_fov = llclamp(new_fov, MIN_FIELD_OF_VIEW, MAX_FIELD_OF_VIEW);
3017
3018 if (new_fov != old_fov)
3019 {
3020 LLMessageSystem* msg = gMessageSystem;
3021 msg->newMessageFast(_PREHASH_AgentFOV);
3022 msg->nextBlockFast(_PREHASH_AgentData);
3023 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
3024 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
3025 msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
3026
3027 msg->nextBlockFast(_PREHASH_FOVBlock);
3028 msg->addU32Fast(_PREHASH_GenCounter, 0);
3029 msg->addF32Fast(_PREHASH_VerticalAngle, new_fov);
3030
3031 gAgent.sendReliableMessage();
3032
3033 // force agent to update dirty patches
3034 gCamera->setDefaultFOV(new_fov);
3035 gCamera->setView(new_fov);
3036 }
3037}
3038
3039class LLViewZoomOut : public view_listener_t
3040{
3041 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3042 {
3043 update_fov(1);
3044 return true;
3045 }
3046};
3047
3048class LLViewZoomIn : public view_listener_t
3049{
3050 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3051 {
3052 update_fov(-1);
3053 return true;
3054 }
3055};
3056
3057class LLViewZoomDefault : public view_listener_t
3058{
3059 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3060 {
3061 F32 old_fov = gCamera->getView();
3062 // for each increment, FoV is 20% bigger
3063 F32 new_fov = DEFAULT_FIELD_OF_VIEW;
3064
3065 if (new_fov != old_fov)
3066 {
3067 LLMessageSystem* msg = gMessageSystem;
3068 msg->newMessageFast(_PREHASH_AgentFOV);
3069 msg->nextBlockFast(_PREHASH_AgentData);
3070 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
3071 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
3072 msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
3073 msg->nextBlockFast(_PREHASH_FOVBlock);
3074 msg->addU32Fast(_PREHASH_GenCounter, 0);
3075 msg->addF32Fast(_PREHASH_VerticalAngle, new_fov);
3076
3077 gAgent.sendReliableMessage();
3078
3079 // force agent to update dirty patches
3080 gCamera->setDefaultFOV(new_fov);
3081 gCamera->setView(new_fov);
3082 }
3083 return true;
3084 }
3085};
3086
3087
3088
3089void toggle_wind_audio(void)
3090{
3091 if (gAudiop)
3092 {
3093 gAudiop->enableWind(!(gAudiop->isWindEnabled()));
3094 }
3095}
3096
3097
3098// Callback for enablement
3099BOOL is_inventory_visible( void* user_data )
3100{
3101 LLInventoryView* iv = reinterpret_cast<LLInventoryView*>(user_data);
3102 if( iv )
3103 {
3104 return iv->getVisible();
3105 }
3106 return FALSE;
3107}
3108
3109void handle_show_newest_map(void*)
3110{
3111 LLFloaterWorldMap::show(NULL, FALSE);
3112}
3113
3114//-------------------------------------------------------------------
3115// Help menu functions
3116//-------------------------------------------------------------------
3117
3118class LLHelpMOTD : public view_listener_t
3119{
3120 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3121 {
3122 LLString::format_map_t args;
3123 args["[MOTD]"] = gAgent.mMOTD;
3124 gViewerWindow->alertXml("MOTD", args, NULL, NULL);
3125 return true;
3126 }
3127};
3128
3129class LLHelpLiveHelp : public view_listener_t
3130{
3131 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3132 {
3133 // the session_id of a 911 session will always be this agent's session id
3134 static LLUUID session_id(LLUUID::null);
3135 if (session_id.isNull())
3136 {
3137 session_id.generate();
3138 }
3139 gIMView->setFloaterOpen(TRUE);
3140 LLDynamicArray<LLUUID> members;
3141 members.put(gAgent.getID());
3142 gIMView->addSession("Help Request", IM_SESSION_911_START, session_id, members); //xui: translate
3143 return true;
3144 }
3145};
3146
3147//
3148// Major mode switching
3149//
3150void reset_view_final( BOOL proceed, void* );
3151
3152void handle_reset_view()
3153{
3154 if( (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode()) && gFloaterCustomize )
3155 {
3156 // Show dialog box if needed.
3157 gFloaterCustomize->askToSaveAllIfDirty( reset_view_final, NULL );
3158 }
3159 else
3160 {
3161 reset_view_final( TRUE, NULL );
3162 }
3163}
3164
3165class LLViewResetView : public view_listener_t
3166{
3167 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3168 {
3169 handle_reset_view();
3170 return true;
3171 }
3172};
3173
3174// Note: extra parameters allow this function to be called from dialog.
3175void reset_view_final( BOOL proceed, void* )
3176{
3177 if( !proceed )
3178 {
3179 return;
3180 }
3181
3182 gAgent.changeCameraToDefault();
3183
3184 gAgent.resetView(!gFloaterTools->getVisible());
3185
3186 gViewerWindow->showCursor();
3187
3188 // Switch back to basic toolset
3189 gCurrentToolset = gBasicToolset;
3190 gBasicToolset->selectFirstTool();
3191 gToolMgr->useSelectedTool( gBasicToolset );
3192}
3193
3194class LLViewLookAtLastChatter : public view_listener_t
3195{
3196 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3197 {
3198 gAgent.lookAtLastChat();
3199 return true;
3200 }
3201};
3202
3203class LLViewMouselook : public view_listener_t
3204{
3205 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3206 {
3207 if (!gAgent.cameraMouselook())
3208 {
3209 gAgent.changeCameraToMouselook();
3210 }
3211 else
3212 {
3213 gAgent.changeCameraToDefault();
3214 }
3215 return true;
3216 }
3217};
3218
3219class LLViewFullscreen : public view_listener_t
3220{
3221 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3222 {
3223 gViewerWindow->toggleFullscreen(TRUE);
3224 return true;
3225 }
3226};
3227
3228class LLViewDefaultUISize : public view_listener_t
3229{
3230 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3231 {
3232 gSavedSettings.setF32("UIScaleFactor", 1.0f);
3233 gSavedSettings.setBOOL("UIAutoScale", FALSE);
3234 gViewerWindow->reshape(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight());
3235 return true;
3236 }
3237};
3238
3239class LLEditDuplicate : public view_listener_t
3240{
3241 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3242 {
3243 if(gEditMenuHandler)
3244 {
3245 gEditMenuHandler->duplicate();
3246 }
3247 return true;
3248 }
3249};
3250
3251class LLEditEnableDuplicate : public view_listener_t
3252{
3253 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3254 {
3255 bool new_value = gEditMenuHandler && gEditMenuHandler->canDuplicate();
3256 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
3257 return true;
3258 }
3259};
3260
3261
3262void disabled_duplicate(void*)
3263{
3264 if (gSelectMgr->getFirstObject())
3265 {
3266 LLNotifyBox::showXml("CopyFailed");
3267 }
3268}
3269
3270void handle_duplicate_in_place(void*)
3271{
3272 llinfos << "handle_duplicate_in_place" << llendl;
3273
3274 LLVector3 offset(0.f, 0.f, 0.f);
3275 gSelectMgr->selectDuplicate(offset, TRUE);
3276}
3277
3278void handle_repeat_duplicate(void*)
3279{
3280 gSelectMgr->repeatDuplicate();
3281}
3282
3283void handle_deed_object_to_group(void*)
3284{
3285 LLUUID group_id;
3286
3287 gSelectMgr->selectGetGroup(group_id);
3288 gSelectMgr->sendOwner(LLUUID::null, group_id, FALSE);
3289 gViewerStats->incStat(LLViewerStats::ST_RELEASE_COUNT);
3290}
3291
3292BOOL enable_deed_object_to_group(void*)
3293{
3294 if(gSelectMgr->isEmpty()) return FALSE;
3295 LLPermissions perm;
3296 LLUUID group_id;
3297
3298 if (gSelectMgr->selectGetGroup(group_id) &&
3299 gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) &&
3300 gSelectMgr->selectGetPermissions(perm) &&
3301 perm.deedToGroup(gAgent.getID(), group_id))
3302 {
3303 return TRUE;
3304 }
3305 return FALSE;
3306}
3307
3308
3309/*
3310 * No longer able to support viewer side manipulations in this way
3311 *
3312void god_force_inv_owner_permissive(LLViewerObject* object,
3313 InventoryObjectList* inventory,
3314 S32 serial_num,
3315 void*)
3316{
3317 typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t;
3318 item_array_t items;
3319
3320 InventoryObjectList::const_iterator inv_it = inventory->begin();
3321 InventoryObjectList::const_iterator inv_end = inventory->end();
3322 for ( ; inv_it != inv_end; ++inv_it)
3323 {
3324 if(((*inv_it)->getType() != LLAssetType::AT_CATEGORY)
3325 && ((*inv_it)->getType() != LLAssetType::AT_ROOT_CATEGORY))
3326 {
3327 LLInventoryObject* obj = *inv_it;
3328 LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem((LLViewerInventoryItem*)obj);
3329 LLPermissions perm(new_item->getPermissions());
3330 perm.setMaskBase(PERM_ALL);
3331 perm.setMaskOwner(PERM_ALL);
3332 new_item->setPermissions(perm);
3333 items.push_back(new_item);
3334 }
3335 }
3336 item_array_t::iterator end = items.end();
3337 item_array_t::iterator it;
3338 for(it = items.begin(); it != end; ++it)
3339 {
3340 // since we have the inventory item in the callback, it should not
3341 // invalidate iteration through the selection manager.
3342 object->updateInventory((*it), TASK_INVENTORY_ITEM_KEY, false);
3343 }
3344}
3345*/
3346
3347void handle_object_owner_permissive(void*)
3348{
3349 // only send this if they're a god.
3350 if(gAgent.isGodlike())
3351 {
3352 // do the objects.
3353 gSelectMgr->setObjectPermissions(PERM_BASE, TRUE, PERM_ALL, TRUE);
3354 gSelectMgr->setObjectPermissions(PERM_OWNER, TRUE, PERM_ALL, TRUE);
3355 }
3356}
3357
3358void handle_object_owner_self(void*)
3359{
3360 // only send this if they're a god.
3361 if(gAgent.isGodlike())
3362 {
3363 gSelectMgr->sendOwner(gAgent.getID(), gAgent.getGroupID(), TRUE);
3364 }
3365}
3366
3367// Shortcut to set owner permissions to not editable.
3368void handle_object_lock(void*)
3369{
3370 gSelectMgr->setObjectPermissions(PERM_OWNER, FALSE, PERM_MODIFY);
3371}
3372
3373void handle_object_asset_ids(void*)
3374{
3375 // only send this if they're a god.
3376 if (gAgent.isGodlike())
3377 {
3378 gSelectMgr->sendGodlikeRequest("objectinfo", "assetids");
3379 }
3380}
3381
3382void handle_force_parcel_owner_to_me(void*)
3383{
3384 gParcelMgr->sendParcelGodForceOwner( gAgent.getID() );
3385}
3386
3387void handle_force_parcel_to_content(void*)
3388{
3389 gParcelMgr->sendParcelGodForceToContent();
3390}
3391
3392void handle_claim_public_land(void*)
3393{
3394 if (gParcelMgr->getSelectionRegion() != gAgent.getRegion())
3395 {
3396 LLNotifyBox::showXml("ClaimPublicLand");
3397 return;
3398 }
3399
3400 LLVector3d west_south_global;
3401 LLVector3d east_north_global;
3402 gParcelMgr->getSelection(west_south_global, east_north_global);
3403 LLVector3 west_south = gAgent.getPosAgentFromGlobal(west_south_global);
3404 LLVector3 east_north = gAgent.getPosAgentFromGlobal(east_north_global);
3405
3406 LLMessageSystem* msg = gMessageSystem;
3407 msg->newMessage("GodlikeMessage");
3408 msg->nextBlock("AgentData");
3409 msg->addUUID("AgentID", gAgent.getID());
3410 msg->addUUID("SessionID", gAgent.getSessionID());
3411 msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
3412 msg->nextBlock("MethodData");
3413 msg->addString("Method", "claimpublicland");
3414 msg->addUUID("Invoice", LLUUID::null);
3415 char buffer[32];
3416 sprintf(buffer, "%f", west_south.mV[VX]);
3417 msg->nextBlock("ParamList");
3418 msg->addString("Parameter", buffer);
3419 sprintf(buffer, "%f", west_south.mV[VY]);
3420 msg->nextBlock("ParamList");
3421 msg->addString("Parameter", buffer);
3422 sprintf(buffer, "%f", east_north.mV[VX]);
3423 msg->nextBlock("ParamList");
3424 msg->addString("Parameter", buffer);
3425 sprintf(buffer, "%f", east_north.mV[VY]);
3426 msg->nextBlock("ParamList");
3427 msg->addString("Parameter", buffer);
3428 gAgent.sendReliableMessage();
3429}
3430
3431//void handle_toggle_parcel_newbie(void*)
3432//{
3433// gParcelMgr->toggleParcelGodReserveForNewbie();
3434//}
3435
3436void on_expunge_user(S32 option, const LLString& text, void*)
3437{
3438 if(option == -1) return;
3439 llinfos << "on_expunge_user(" << option << "," << text << ")" << llendl;
3440 LLMessageSystem* msg = gMessageSystem;
3441 LLUUID user_id;
3442 if(user_id.set(text))
3443 {
3444 msg->newMessage("GodExpungeUser");
3445 msg->nextBlock("AgentData");
3446 msg->addUUID("AgentID", gAgent.getID());
3447 msg->addUUID("SessionID", gAgent.getSessionID());
3448 msg->nextBlock("ExpungeData");
3449 msg->addUUID("AgentID", user_id);
3450 msg->sendReliable(gUserServer);
3451 }
3452 else
3453 {
3454 gViewerWindow->alertXml("InvalidUUID");
3455 }
3456}
3457
3458void handle_god_expunge_user(void*)
3459{
3460 gViewerWindow->alertXmlEditText("ExpungeUser", LLString::format_map_t(),
3461 NULL, NULL,
3462 on_expunge_user, NULL);
3463}
3464
3465void handle_god_request_havok(void *)
3466{
3467 if (gAgent.isGodlike())
3468 {
3469 gSelectMgr->sendGodlikeRequest("havok", "infoverbose");
3470 }
3471}
3472
3473//void handle_god_request_foo(void *)
3474//{
3475// if (gAgent.isGodlike())
3476// {
3477// gSelectMgr->sendGodlikeRequest(GOD_WANTS_FOO);
3478// }
3479//}
3480
3481//void handle_god_request_terrain_save(void *)
3482//{
3483// if (gAgent.isGodlike())
3484// {
3485// gSelectMgr->sendGodlikeRequest("terrain", "save");
3486// }
3487//}
3488
3489//void handle_god_request_terrain_load(void *)
3490//{
3491// if (gAgent.isGodlike())
3492// {
3493// gSelectMgr->sendGodlikeRequest("terrain", "load");
3494// }
3495//}
3496
3497
3498// HACK for easily testing new avatar geometry
3499void handle_god_request_avatar_geometry(void *)
3500{
3501 if (gAgent.isGodlike())
3502 {
3503 gSelectMgr->sendGodlikeRequest("avatar toggle", NULL);
3504 }
3505}
3506
3507
3508void handle_show_overlay_title(void*)
3509{
3510 gShowOverlayTitle = !gShowOverlayTitle;
3511 gSavedSettings.setBOOL("ShowOverlayTitle", gShowOverlayTitle);
3512}
3513
3514void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
3515{
3516 if(gAgent.cameraMouselook())
3517 {
3518 gAgent.changeCameraToDefault();
3519 }
3520 //gInventoryView->setPanelOpen(TRUE);
3521
3522 LLViewerObject* object = NULL;
3523 LLSelectNode* node = gSelectMgr->getFirstRootNode();
3524 if(!node) return;
3525 object = node->getObject();
3526 if(!object) return;
3527 LLViewerRegion* region = object->getRegion();
3528 char* error = NULL;
3529
3530 // Check conditions that we can't deal with, building a list of
3531 // everything that we'll actually be derezzing.
3532 LLDynamicArray<LLViewerObject*> derez_objects;
3533 BOOL can_derez_current;
3534 for( ; node != NULL; node = gSelectMgr->getNextRootNode())
3535 {
3536 object = node->getObject();
3537 if(!object || !node->mValid) continue;
3538 if(object->getRegion() != region)
3539 {
3540 // Derez doesn't work at all if the some of the objects
3541 // are in regions besides the first object selected.
3542
3543 // ...crosses region boundaries
3544 error = "AcquireErrorObjectSpan";
3545 break;
3546 }
3547 if (object->isAvatar())
3548 {
3549 // ...don't acquire avatars
3550 continue;
3551 }
3552
3553 // If AssetContainers are being sent back, they will appear as
3554 // boxes in the owner's inventory.
3555 if (object->getNVPair("AssetContainer")
3556 && dest != DRD_RETURN_TO_OWNER)
3557 {
3558 // this object is an asset container, derez its contents, not it
3559 llwarns << "Attempt to derez deprecated AssetContainer object type not supported." << llendl;
3560 /*
3561 object->requestInventory(container_inventory_arrived,
3562 (void *)(BOOL)(DRD_TAKE_INTO_AGENT_INVENTORY == dest));
3563 */
3564 continue;
3565 }
3566 can_derez_current = FALSE;
3567 switch(dest)
3568 {
3569 case DRD_TAKE_INTO_AGENT_INVENTORY:
3570 case DRD_TRASH:
3571 if( (node->mPermissions->allowTransferTo(gAgent.getID()) && object->permModify())
3572 || (node->allowOperationOnNode(PERM_OWNER, GP_OBJECT_MANIPULATE)) )
3573 {
3574 can_derez_current = TRUE;
3575 }
3576 break;
3577
3578 case DRD_RETURN_TO_OWNER:
3579 can_derez_current = TRUE;
3580 break;
3581
3582 default:
3583 if((node->mPermissions->allowTransferTo(gAgent.getID())
3584 && object->permCopy())
3585 || gAgent.isGodlike())
3586 {
3587 can_derez_current = TRUE;
3588 }
3589 break;
3590 }
3591 if(can_derez_current)
3592 {
3593 derez_objects.put(object);
3594 }
3595 }
3596
3597 // This constant is based on (1200 - HEADER_SIZE) / 4 bytes per
3598 // root. I lopped off a few (33) to provide a bit
3599 // pad. HEADER_SIZE is currently 67 bytes, most of which is UUIDs.
3600 // This gives us a maximum of 63500 root objects - which should
3601 // satisfy anybody.
3602 const S32 MAX_ROOTS_PER_PACKET = 250;
3603 const S32 MAX_PACKET_COUNT = 254;
3604 F32 packets = ceil((F32)derez_objects.count() / (F32)MAX_ROOTS_PER_PACKET);
3605 if(packets > (F32)MAX_PACKET_COUNT)
3606 {
3607 error = "AcquireErrorTooManyObjects";
3608 }
3609
3610 if(!error && derez_objects.count() > 0)
3611 {
3612 U8 d = (U8)dest;
3613 LLUUID tid;
3614 tid.generate();
3615 U8 packet_count = (U8)packets;
3616 S32 object_index = 0;
3617 S32 objects_in_packet = 0;
3618 LLMessageSystem* msg = gMessageSystem;
3619 for(U8 packet_number = 0;
3620 packet_number < packet_count;
3621 ++packet_number)
3622 {
3623 msg->newMessageFast(_PREHASH_DeRezObject);
3624 msg->nextBlockFast(_PREHASH_AgentData);
3625 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
3626 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
3627 msg->nextBlockFast(_PREHASH_AgentBlock);
3628 msg->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
3629 msg->addU8Fast(_PREHASH_Destination, d);
3630 msg->addUUIDFast(_PREHASH_DestinationID, dest_id);
3631 msg->addUUIDFast(_PREHASH_TransactionID, tid);
3632 msg->addU8Fast(_PREHASH_PacketCount, packet_count);
3633 msg->addU8Fast(_PREHASH_PacketNumber, packet_number);
3634 objects_in_packet = 0;
3635 while((object_index < derez_objects.count())
3636 && (objects_in_packet++ < MAX_ROOTS_PER_PACKET))
3637
3638 {
3639 object = derez_objects.get(object_index++);
3640 msg->nextBlockFast(_PREHASH_ObjectData);
3641 msg->addU32Fast(_PREHASH_ObjectLocalID, object->getLocalID());
3642 // VEFFECT: DerezObject
3643 LLHUDEffectSpiral* effectp = (LLHUDEffectSpiral*)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
3644 effectp->setPositionGlobal(object->getPositionGlobal());
3645 effectp->setColor(LLColor4U(gAgent.getEffectColor()));
3646 }
3647 msg->sendReliable(region->getHost());
3648 }
3649 make_ui_sound("UISndObjectRezOut");
3650
3651 // Busy count decremented by inventory update, so only increment
3652 // if will be causing an update.
3653 if (dest != DRD_RETURN_TO_OWNER)
3654 {
3655 gViewerWindow->getWindow()->incBusyCount();
3656 }
3657 }
3658 else if(error)
3659 {
3660 gViewerWindow->alertXml(error);
3661 }
3662}
3663
3664class LLToolsTakeCopy : public view_listener_t
3665{
3666 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3667 {
3668 if (gSelectMgr->isEmpty()) return true;
3669
3670 const LLUUID& category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT);
3671 derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id);
3672
3673 // Only deselect if we're not building
3674 if (!gToolMgr->inEdit())
3675 {
3676 gSelectMgr->deselectTransient();
3677 }
3678 return true;
3679 }
3680};
3681
3682
3683void callback_return_to_owner(S32 option, void* data)
3684{
3685 if (0 == option)
3686 {
3687 // Ignore category ID for this derez destination.
3688 derez_objects(DRD_RETURN_TO_OWNER, LLUUID::null);
3689 }
3690}
3691
3692// You can return an object to its owner if it is on your land.
3693class LLObjectReturn : public view_listener_t
3694{
3695 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3696 {
3697 if (gSelectMgr->isEmpty()) return true;
3698
3699 gViewerWindow->alertXml("ReturnToOwner",
3700 callback_return_to_owner,
3701 NULL);
3702 return true;
3703 }
3704};
3705
3706
3707// Allow return to owner if one or more of the selected items is
3708// over land you own.
3709class LLObjectEnableReturn : public view_listener_t
3710{
3711 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
3712 {
3713#ifdef HACKED_GODLIKE_VIEWER
3714 bool new_value = true;
3715#else
3716 bool new_value = false;
3717 if (gAgent.isGodlike())
3718 {
3719 new_value = true;
3720 }
3721 else
3722 {
3723 LLViewerRegion* region = gAgent.getRegion();
3724 if (region)
3725 {
3726 // Estate owners and managers can always return objects.
3727 if (region->canManageEstate())
3728 {
3729 new_value = true;
3730 }
3731 else
3732 {
3733 LLViewerObject* obj = NULL;
3734 for(obj = gSelectMgr->getFirstRootObject();
3735 obj;
3736 obj = gSelectMgr->getNextRootObject())
3737 {
3738 if (obj->isOverAgentOwnedLand()
3739 || obj->isOverGroupOwnedLand()
3740 || obj->permModify())
3741 {
3742 new_value = true;
3743 break;
3744 }
3745 }
3746 }
3747 }
3748 }
3749#endif
3750 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
3751 return true;
3752 }
3753};
3754
3755void force_take_copy(void*)
3756{
3757 if (gSelectMgr->isEmpty()) return;
3758 const LLUUID& category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT);
3759 derez_objects(DRD_FORCE_TO_GOD_INVENTORY, category_id);
3760
3761 // Only deselect if we're not building
3762 if (!gToolMgr->inEdit())
3763 {
3764 gSelectMgr->deselectTransient();
3765 }
3766}
3767#ifdef _CORY_TESTING
3768
3769void force_export_copy(void*)
3770{
3771 LLViewerObject* object = NULL;
3772 LLSelectNode* node = gSelectMgr->getFirstNode();
3773 if(!node) return;
3774 object = node->getObject();
3775 if(!object) return;
3776
3777
3778 LLString proposed_name;
3779 proposed_name.append(node->mName);
3780 proposed_name.append( ".slg" );
3781
3782 LLViewerRegion* region = object->getRegion();
3783
3784 // Check conditions that we can't deal with, building a list of
3785 // everything that we'll actually be derezzing.
3786
3787 std::vector<LLViewerObject*> export_objects;
3788 std::vector<std::string> export_names;
3789 std::vector<std::string> export_descriptions;
3790
3791 S32 object_index = 0;
3792
3793 for( ; node != NULL; node = gSelectMgr->getNextNode())
3794 {
3795 object = node->getObject();
3796 if(!object || !node->mValid)
3797 {
3798 // Clicked cancel
3799 return;
3800 }
3801 if(object->getRegion() != region)
3802 {
3803 // Clicked cancel
3804 return;
3805 }
3806 if (object->isAvatar())
3807 {
3808 continue;
3809 }
3810
3811 if (object->getNVPair("AssetContainer"))
3812 {
3813 continue;
3814 }
3815 export_objects.push_back(node->getObject());
3816 export_names.push_back(node->mName);
3817 export_descriptions.push_back(node->mDescription);
3818 }
3819
3820 if (export_objects.empty())
3821 {
3822 return;
3823 }
3824
3825 // pick a save file
3826 LLFilePicker& picker = LLFilePicker::instance();
3827 if (!picker.getSaveFile(LLFilePicker::FFSAVE_GEOMETRY, proposed_name))
3828 {
3829 // Clicked cancel
3830 return;
3831 }
3832
3833 // Copy the directory + file name
3834 char filepath[LL_MAX_PATH];
3835 strcpy(filepath, picker.getFirstFile());
3836
3837 apr_file_t* fp = ll_apr_file_open(filepath, LL_APR_W);
3838
3839 if (!fp)
3840 {
3841 return;
3842 }
3843
3844 object = export_objects[object_index];
3845 LLVector3 baseoffset = object->getPositionRegion();
3846
3847 apr_file_printf(fp, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n");
3848 apr_file_printf(fp, "<LindenGeometry>\n");
3849
3850 while(object_index < export_objects.size())
3851 {
3852 apr_file_printf(fp, "<Object\n");
3853 apr_file_printf(fp, "\tShape='%s'\n", export_names[object_index].c_str());
3854 apr_file_printf(fp, "\tDescription='%s'\n", export_descriptions[object_index].c_str());
3855
3856 apr_file_printf(fp, "\tPCode='%d'\n", (U32)object->getPCode());
3857 apr_file_printf(fp, "\tMaterial='%d'\n", object->getMaterial());
3858 apr_file_printf(fp, "\tScale='%5f %5f %5f'\n", object->getScale().mV[VX], object->getScale().mV[VY], object->getScale().mV[VZ]);
3859 LLVector3 delta = object->getPositionRegion() - baseoffset;
3860 LLQuaternion rot = object->getRotationRegion();
3861 apr_file_printf(fp, "\tOffset='%5f %5f %5f'\n", delta.mV[VX], delta.mV[VY], delta.mV[VZ]);
3862 apr_file_printf(fp, "\tOrientation='%5f %5f %5f %5f'\n", rot.mQ[VX], rot.mQ[VY], rot.mQ[VZ], rot.mQ[VS]);
3863 const LLProfileParams pparams = object->getVolume()->getProfile().mParams;
3864 apr_file_printf(fp, "\tShapeProfile='%d %f %f %f'\n", pparams.getCurveType(), pparams.getBegin(), pparams.getEnd(), pparams.getHollow());
3865 const LLPathParams paparams = object->getVolume()->getPath().mParams;
3866 apr_file_printf(fp, "\tShapePath='%d %f %f %f %f %f %f %f %f %f %f %f %f %f'\n",
3867 paparams.getCurveType(), paparams.getBegin(), paparams.getEnd(), paparams.getTwist(), paparams.getTwistBegin(), paparams.getScaleX(), paparams.getScaleY(),
3868 paparams.getShearX(), paparams.getShearY(), paparams.getRadiusOffset(), paparams.getTaperX(), paparams.getTaperY(),
3869 paparams.getRevolutions(), paparams.getSkew());
3870 S32 face, numfaces;
3871 numfaces = object->getNumTEs();
3872 apr_file_printf(fp, "\tNumberOfFaces='%d'>\n", numfaces);
3873 for (face = 0; face < numfaces; face++)
3874 {
3875 const LLTextureEntry *te = object->getTE(face);
3876 LLColor4 color = te->getColor();
3877 apr_file_printf(fp, "\t<Face\n\t\tFaceColor='%d %5f %5f %5f %5f'\n", face, color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW]);
3878
3879 char texture[UUID_STR_LENGTH];
3880 LLUUID texid = te->getID();
3881 texid.toString(texture);
3882 F32 sx, sy, ox, oy;
3883 te->getScale(&sx, &sy);
3884 te->getOffset(&ox, &oy);
3885
3886 apr_file_printf(fp, "\t\tFace='%d %5f %5f %5f %5f %5f %d %s'\n\t/>\n", face, sx, sy, ox, oy, te->getRotation(), te->getBumpShinyFullbright(), texture);
3887 }
3888 apr_file_printf(fp, "</Object>\n");
3889 object = export_objects[++object_index];
3890 }
3891
3892 apr_file_printf(fp, "</LindenGeometry>\n");
3893
3894 fclose(fp);
3895}
3896
3897void undo_find_local_contact_point(LLVector3 &contact,
3898 const LLVector3& surface_norm,
3899 const LLQuaternion& rot,
3900 const LLVector3& scale )
3901{
3902 LLVector3 local_norm = surface_norm;
3903 local_norm.rotVec( ~rot );
3904
3905 LLVector3 v[6];
3906 v[0].mV[VX] = -1.f;
3907 v[1].mV[VX] = 1.f;
3908
3909 v[2].mV[VY] = -1.f;
3910 v[3].mV[VY] = 1.f;
3911
3912 v[4].mV[VZ] = -1.f;
3913 v[5].mV[VZ] = 1.f;
3914
3915 contact = v[0];
3916 F32 cur_val = 0;
3917
3918 for( S32 i = 0; i < 6; i++ )
3919 {
3920 F32 val = v[i] * local_norm;
3921 if( val < cur_val )
3922 {
3923 contact = v[i];
3924 cur_val = val;
3925 }
3926 }
3927
3928 contact.mV[VX] *= 0.5f * scale.mV[VX];
3929 contact.mV[VY] *= 0.5f * scale.mV[VY];
3930 contact.mV[VZ] *= 0.5f * scale.mV[VZ];
3931 contact.rotVec( rot );
3932}
3933
3934
3935
3936void force_import_geometry(void*)
3937{
3938 LLFilePicker& picker = LLFilePicker::instance();
3939 if (!picker.getOpenFile(LLFilePicker::FFLOAD_GEOMETRY))
3940 {
3941 llinfos << "Couldn't import objects from file" << llendl;
3942 return;
3943 }
3944
3945 char directory[LL_MAX_PATH];
3946 strcpy(directory, picker.getFirstFile());
3947
3948 llinfos << "Loading LSG file " << directory << llendl;
3949 LLXmlTree *xmlparser = new LLXmlTree();
3950 xmlparser->parseFile(directory, TRUE);
3951 LLXmlTreeNode *root = xmlparser->getRoot();
3952 if( !root )
3953 {
3954 return;
3955 }
3956 // header
3957 if( !root->hasName( "LindenGeometry" ) )
3958 {
3959 llwarns << "Invalid LindenGeometry file header: " << directory << llendl;
3960 return;
3961 }
3962 // objects
3963 for (LLXmlTreeNode *child = root->getChildByName( "Object" );
3964 child;
3965 child = root->getNextNamedChild())
3966 {
3967 // get object data
3968 char name[255]; // Shape
3969 char description[255]; // Description
3970 U32 material; // Material
3971 F32 sx, sy, sz; // Scale
3972 LLVector3 scale;
3973 F32 ox, oy, oz; // Offset
3974 LLVector3 offset;
3975 F32 rx, ry, rz, rs; // Orientation
3976 LLQuaternion rot;
3977 U32 curve;
3978 F32 begin;
3979 F32 end;
3980 F32 hollow;
3981 F32 twist;
3982 F32 scx, scy;
3983 F32 shx, shy;
3984 F32 twist_begin;
3985 F32 radius_offset;
3986 F32 tx, ty;
3987 F32 revolutions;
3988 F32 skew;
3989 S32 faces;
3990 U32 pcode;
3991 U32 flags = FLAGS_CREATE_SELECTED;
3992
3993 LLString attribute;
3994
3995 S32 count = 0;
3996
3997 child->getAttributeString("PCode", &attribute);
3998 pcode = atoi(attribute.c_str());
3999 child->getAttributeString("Shape", &attribute);
4000 sscanf(attribute.c_str(), "%s", name);
4001 child->getAttributeString("Description", &attribute);
4002 sscanf(attribute.c_str(), "%s", description);
4003 child->getAttributeString("Material", &attribute);
4004 material = atoi(attribute.c_str());
4005 child->getAttributeString("Scale", &attribute);
4006 sscanf(attribute.c_str(), "%f %f %f", &sx, &sy, &sz);
4007 scale.setVec(sx, sy, sz);
4008 child->getAttributeString("Offset", &attribute);
4009 sscanf(attribute.c_str(), "%f %f %f", &ox, &oy, &oz);
4010 offset.setVec(ox, oy, oz);
4011 child->getAttributeString("Orientation", &attribute);
4012 sscanf(attribute.c_str(), "%f %f %f %f", &rx, &ry, &rz, &rs);
4013 rot.mQ[VX] = rx;
4014 rot.mQ[VY] = ry;
4015 rot.mQ[VZ] = rz;
4016 rot.mQ[VS] = rs;
4017
4018 child->getAttributeString("ShapeProfile", &attribute);
4019 sscanf(attribute.c_str(), "%d %f %f %f", &curve, &begin, &end, &hollow);
4020 LLProfileParams pparams(curve, begin, end, hollow);
4021 child->getAttributeString("ShapePath", &attribute);
4022 sscanf(attribute.c_str(), "%d %f %f %f %f %f %f %f %f %f %f %f %f %f",
4023 &curve, &begin, &end, &twist, &twist_begin, &scx, &scy, &shx, &shy, &radius_offset, &tx, &ty, &revolutions, &skew);
4024 LLPathParams paparams(curve, begin, end, scx, scy, shx, shy, twist, twist_begin, radius_offset, tx, ty, revolutions, skew);
4025 child->getAttributeString("NumberOfFaces", &attribute);
4026 faces = atoi(attribute.c_str());
4027
4028
4029
4030 gMessageSystem->newMessageFast(_PREHASH_ObjectAdd);
4031 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
4032 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
4033 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
4034 gMessageSystem->addUUIDFast(_PREHASH_GroupID, gAgent.getGroupID());
4035
4036 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
4037 gMessageSystem->addU8Fast(_PREHASH_PCode, pcode);
4038 gMessageSystem->addU8Fast(_PREHASH_Material, material);
4039 gMessageSystem->addU32Fast(_PREHASH_AddFlags, flags );
4040 pparams.packMessage(gMessageSystem);
4041 paparams.packMessage(gMessageSystem);
4042
4043 LLVector3 forward;
4044 forward.setVec(3.f, 0.f, 1.f);
4045 forward = forward * gAgent.getQuat();
4046
4047 LLVector3 start = gAgent.getPositionAgent() + forward;
4048
4049 start += offset;
4050
4051 // offset position to make up for error introduced by placement code
4052 LLVector3 normal(0.f, 0.f, 1.f);
4053 LLVector3 delta;
4054
4055 undo_find_local_contact_point(delta, normal, rot, scale);
4056
4057 start += delta;
4058
4059 gMessageSystem->addVector3Fast(_PREHASH_Scale, scale );
4060 gMessageSystem->addQuatFast(_PREHASH_Rotation, rot );
4061 gMessageSystem->addVector3Fast(_PREHASH_RayStart, start );
4062 gMessageSystem->addVector3Fast(_PREHASH_RayEnd, start );
4063 gMessageSystem->addBOOLFast(_PREHASH_BypassRaycast, TRUE );
4064 gMessageSystem->addBOOLFast(_PREHASH_RayEndIsIntersection, FALSE );
4065
4066 U8 state = 0;
4067 gMessageSystem->addU8Fast(_PREHASH_State, state);
4068
4069 LLUUID ray_target_id;
4070 gMessageSystem->addUUIDFast(_PREHASH_RayTargetID, ray_target_id );
4071
4072 /* Setting TE info through ObjectAdd is no longer supported.
4073 LLPrimitive temp_primitive;
4074 temp_primitive.setNumTEs(faces);
4075 for (LLXmlTreeNode *face = child->getChildByName( "Face" );
4076 face;
4077 face = child->getNextNamedChild())
4078 {
4079 // read the faces
4080 U32 facenumber;
4081 LLColor4 color;
4082 char texture[UUID_STR_LENGTH];
4083 LLUUID texid;
4084 texid.toString(texture);
4085 F32 sx, sy, ox, oy, rot;
4086 U8 bump;
4087 LLTextureEntry te;
4088
4089 face->getAttributeString("FaceColor", &attribute);
4090 sscanf(attribute, "%d %f %f %f %f", &facenumber, &color.mV[VX], &color.mV[VY], &color.mV[VZ], &color.mV[VW]);
4091 face->getAttributeString("Face", &attribute);
4092 sscanf(attribute, "%d %f %f %f %f %f %d %s", &facenumber, &sx, &sy, &ox, &oy, &rot, &bump, texture);
4093 texid.set(texture);
4094 te.setColor(color);
4095 te.setBumpShinyFullbright(bump);
4096 te.setID(texid);
4097 te.setRotation(rot);
4098 te.setOffset(ox, oy);
4099 te.setScale(sx, sy);
4100
4101 temp_primitive.setTE(facenumber, te);
4102 }
4103
4104 temp_primitive.packTEMessage(gMessageSystem);
4105 */
4106 gMessageSystem->sendReliable(gAgent.getRegionHost());
4107 }
4108
4109}
4110#endif
4111
4112void handle_take()
4113{
4114 // we want to use the folder this was derezzed from if it's
4115 // available. Otherwise, derez to the normal place.
4116 if(gSelectMgr->isEmpty()) return;
4117 LLSelectNode* node = NULL;
4118 LLViewerObject* object = NULL;
4119 BOOL you_own_everything = TRUE;
4120
4121 BOOL locked_but_takeable_object = FALSE;
4122 LLUUID category_id;
4123 for(node = gSelectMgr->getFirstRootNode();
4124 node != NULL;
4125 node = gSelectMgr->getNextRootNode())
4126 {
4127 object = node->getObject();
4128 if(object)
4129 {
4130 if(!object->permYouOwner())
4131 {
4132 you_own_everything = FALSE;
4133 }
4134
4135 if(!object->permMove())
4136
4137 {
4138
4139 locked_but_takeable_object = TRUE;
4140
4141 }
4142 }
4143 if(node->mFolderID.notNull())
4144 {
4145 if(category_id.isNull())
4146 {
4147 category_id = node->mFolderID;
4148 }
4149 else if(category_id != node->mFolderID)
4150 {
4151 // we have found two potential destinations. break out
4152 // now and send to the default location.
4153 category_id.setNull();
4154 break;
4155 }
4156 }
4157 }
4158 if(category_id.notNull())
4159 {
4160 // there is an unambiguous destination. See if this agent has
4161 // such a location and it is not in the trash.
4162 if(!gInventory.getCategory(category_id))
4163 {
4164 // nope, set to NULL.
4165 category_id.setNull();
4166 }
4167 if(category_id.notNull())
4168 {
4169 LLUUID trash;
4170 trash = gInventory.findCategoryUUIDForType(LLAssetType::AT_TRASH);
4171 if(category_id == trash || gInventory.isObjectDescendentOf(category_id, trash))
4172 {
4173 category_id.setNull();
4174 }
4175 }
4176 }
4177 if(category_id.isNull())
4178 {
4179 category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT);
4180 }
4181 LLUUID* cat_id = new LLUUID(category_id);
4182 if(locked_but_takeable_object ||
4183
4184 !you_own_everything)
4185 {
4186
4187 if(locked_but_takeable_object && you_own_everything)
4188 {
4189
4190 gViewerWindow->alertXml("ConfirmObjectTakeLock",
4191 confirm_take,
4192 (void*)cat_id);
4193
4194 }
4195 else if(!locked_but_takeable_object && !you_own_everything)
4196 {
4197
4198 gViewerWindow->alertXml("ConfirmObjectTakeNoOwn",
4199 confirm_take,
4200 (void*)cat_id);
4201 }
4202 else
4203 {
4204 gViewerWindow->alertXml("ConfirmObjectTakeLockNoOwn",
4205 confirm_take,
4206 (void*)cat_id);
4207 }
4208
4209
4210 }
4211
4212 else
4213 {
4214 confirm_take(0, (void*)cat_id);
4215 }
4216}
4217
4218void confirm_take(S32 option, void* data)
4219{
4220 LLUUID* cat_id = (LLUUID*)data;
4221 if(!cat_id) return;
4222 if(enable_take() && (option == 0))
4223 {
4224 derez_objects(DRD_TAKE_INTO_AGENT_INVENTORY, *cat_id);
4225 }
4226 delete cat_id;
4227}
4228
4229// You can take an item when it is public and transferrable, or when
4230// you own it. We err on the side of enabling the item when at least
4231// one item selected can be copied to inventory.
4232BOOL enable_take()
4233{
4234 if (sitting_on_selection())
4235 {
4236 return FALSE;
4237 }
4238
4239 LLViewerObject* object = NULL;
4240 for(LLSelectNode* node = gSelectMgr->getFirstRootNode();
4241 node != NULL;
4242 node = gSelectMgr->getNextRootNode())
4243 {
4244 object = node->getObject();
4245 if(!object || !node->mValid) continue;
4246 if (object->isAvatar())
4247 {
4248 // ...don't acquire avatars
4249 continue;
4250 }
4251
4252#ifdef HACKED_GODLIKE_VIEWER
4253 return TRUE;
4254#else
4255# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
4256 if (!gInProductionGrid && gAgent.isGodlike())
4257 {
4258 return TRUE;
4259 }
4260# endif
4261 if((node->mPermissions->allowTransferTo(gAgent.getID())
4262 && object->permModify())
4263 || (node->mPermissions->getOwner() == gAgent.getID()))
4264 {
4265 return TRUE;
4266 }
4267#endif
4268 }
4269 return FALSE;
4270}
4271
4272class LLToolsBuyOrTake : public view_listener_t
4273{
4274 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4275 {
4276 if (gSelectMgr->isEmpty())
4277 {
4278 return true;
4279 }
4280
4281 if (is_selection_buy_not_take())
4282 {
4283 S32 total_price = selection_price();
4284
4285 if (total_price <= gStatusBar->getBalance())
4286 {
4287 handle_buy(NULL);
4288 }
4289 else
4290 {
4291 LLFloaterBuyCurrency::buyCurrency(
4292 "Buying this costs", total_price);
4293 }
4294 }
4295 else
4296 {
4297 handle_take();
4298 }
4299 return true;
4300 }
4301};
4302
4303class LLToolsEnableBuyOrTake : public view_listener_t
4304{
4305 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4306 {
4307 bool is_buy = is_selection_buy_not_take();
4308 bool new_value = is_buy ? enable_buy(NULL) : enable_take();
4309 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4310
4311 // Update label
4312 LLString label;
4313 LLString buy_text;
4314 LLString take_text;
4315 LLString param = userdata["data"].asString();
4316 LLString::size_type offset = param.find(",");
4317 if (offset != param.npos)
4318 {
4319 buy_text = param.substr(0, offset);
4320 take_text = param.substr(offset+1);
4321 }
4322 if (is_buy)
4323 {
4324 label = buy_text;
4325 }
4326 else
4327 {
4328 label = take_text;
4329 }
4330 gMenuHolder->childSetText("Pie Object Take", label);
4331 gMenuHolder->childSetText("Menu Object Take", label);
4332
4333 return true;
4334 }
4335};
4336
4337// This is a small helper function to determine if we have a buy or a
4338// take in the selection. This method is to help with the aliasing
4339// problems of putting buy and take in the same pie menu space. After
4340// a fair amont of discussion, it was determined to prefer buy over
4341// take. The reasoning follows from the fact that when users walk up
4342// to buy something, they will click on one or more items. Thus, if
4343// anything is for sale, it becomes a buy operation, and the server
4344// will group all of the buy items, and copyable/modifiable items into
4345// one package and give the end user as much as the permissions will
4346// allow. If the user wanted to take something, they will select fewer
4347// and fewer items until only 'takeable' items are left. The one
4348// exception is if you own everything in the selection that is for
4349// sale, in this case, you can't buy stuff from yourself, so you can
4350// take it.
4351// return value = TRUE if selection is a 'buy'.
4352// FALSE if selection is a 'take'
4353BOOL is_selection_buy_not_take()
4354{
4355 LLViewerObject* obj = NULL;
4356 for(LLSelectNode* node = gSelectMgr->getFirstRootNode();
4357 node != NULL;
4358 node = gSelectMgr->getNextRootNode())
4359 {
4360 obj = node->getObject();
4361 if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale()))
4362 {
4363 // you do not own the object and it is for sale, thus,
4364 // it's a buy
4365 return TRUE;
4366 }
4367 }
4368 return FALSE;
4369}
4370
4371S32 selection_price()
4372{
4373 LLViewerObject* obj = NULL;
4374 S32 total_price = 0;
4375 for(LLSelectNode* node = gSelectMgr->getFirstRootNode();
4376 node != NULL;
4377 node = gSelectMgr->getNextRootNode())
4378 {
4379 obj = node->getObject();
4380 if(obj && !(obj->permYouOwner()) && (node->mSaleInfo.isForSale()))
4381 {
4382 // you do not own the object and it is for sale.
4383 // Add its price.
4384 total_price += node->mSaleInfo.getSalePrice();
4385 }
4386 }
4387
4388 return total_price;
4389}
4390
4391void callback_show_buy_currency(S32 option, void*)
4392{
4393 if (0 == option)
4394 {
4395 llinfos << "Loading page " << BUY_CURRENCY_URL << llendl;
4396 LLWeb::loadURL(BUY_CURRENCY_URL);
4397 }
4398}
4399
4400
4401void show_buy_currency(const char* extra)
4402{
4403 // Don't show currency web page for branded clients.
4404
4405 std::ostringstream mesg;
4406 if (extra != NULL)
4407 {
4408 mesg << extra << "\n \n";
4409 }
4410 mesg << "Go to " << BUY_CURRENCY_URL << "\nfor information on purchasing currency?";
4411
4412 LLString::format_map_t args;
4413 args["[EXTRA]"] = extra;
4414 args["[URL]"] = BUY_CURRENCY_URL;
4415 gViewerWindow->alertXml("PromptGoToCurrencyPage", args,
4416 callback_show_buy_currency);
4417}
4418
4419void handle_buy_currency(void*)
4420{
4421// LLFloaterBuyCurrency::buyCurrency();
4422}
4423
4424void handle_buy(void*)
4425{
4426 if (gSelectMgr->isEmpty()) return;
4427
4428 LLSaleInfo sale_info;
4429 BOOL valid = gSelectMgr->selectGetSaleInfo(sale_info);
4430 if (!valid) return;
4431
4432 if (sale_info.getSaleType() == LLSaleInfo::FS_CONTENTS)
4433 {
4434 handle_buy_contents(sale_info);
4435 }
4436 else
4437 {
4438 handle_buy_object(sale_info);
4439 }
4440}
4441
4442class LLObjectBuy : public view_listener_t
4443{
4444 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4445 {
4446 handle_buy(NULL);
4447 return true;
4448 }
4449};
4450
4451BOOL sitting_on_selection()
4452{
4453 LLSelectNode* node = gSelectMgr->getFirstRootNode();
4454 if (!node)
4455 {
4456 return FALSE;
4457 }
4458
4459 if (!node->mValid)
4460 {
4461 return FALSE;
4462 }
4463
4464 LLViewerObject* root_object = node->getObject();
4465 if (!root_object)
4466 {
4467 return FALSE;
4468 }
4469
4470 // Need to determine if avatar is sitting on this object
4471 LLVOAvatar* avatar = gAgent.getAvatarObject();
4472 if (!avatar)
4473 {
4474 return FALSE;
4475 }
4476
4477 return (avatar->mIsSitting && avatar->getRoot() == root_object);
4478}
4479
4480class LLToolsSaveToInventory : public view_listener_t
4481{
4482 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4483 {
4484 if(enable_save_into_inventory(NULL))
4485 {
4486 derez_objects(DRD_SAVE_INTO_AGENT_INVENTORY, LLUUID::null);
4487 }
4488 return true;
4489 }
4490};
4491
4492class LLToolsSaveToObjectInventory : public view_listener_t
4493{
4494 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4495 {
4496 if(gSelectMgr)
4497 {
4498 LLSelectNode* node = gSelectMgr->getFirstRootNode();
4499 if(node && (node->mValid) && (!node->mFromTaskID.isNull()))
4500 {
4501 // *TODO: check to see if the fromtaskid object exists.
4502 derez_objects(DRD_SAVE_INTO_TASK_INVENTORY, node->mFromTaskID);
4503 }
4504 }
4505 return true;
4506 }
4507};
4508
4509// Round the position of all root objects to the grid
4510class LLToolsSnapObjectXY : public view_listener_t
4511{
4512 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4513 {
4514 F64 snap_size = (F64)gSavedSettings.getF32("GridResolution");
4515
4516 LLViewerObject* obj;
4517 for (obj = gSelectMgr->getFirstRootObject();
4518 obj != NULL;
4519 obj = gSelectMgr->getNextRootObject())
4520 {
4521 if (obj->permModify())
4522 {
4523 LLVector3d pos_global = obj->getPositionGlobal();
4524 F64 round_x = fmod(pos_global.mdV[VX], snap_size);
4525 if (round_x < snap_size * 0.5)
4526 {
4527 // closer to round down
4528 pos_global.mdV[VX] -= round_x;
4529 }
4530 else
4531 {
4532 // closer to round up
4533 pos_global.mdV[VX] -= round_x;
4534 pos_global.mdV[VX] += snap_size;
4535 }
4536
4537 F64 round_y = fmod(pos_global.mdV[VY], snap_size);
4538 if (round_y < snap_size * 0.5)
4539 {
4540 pos_global.mdV[VY] -= round_y;
4541 }
4542 else
4543 {
4544 pos_global.mdV[VY] -= round_y;
4545 pos_global.mdV[VY] += snap_size;
4546 }
4547
4548 obj->setPositionGlobal(pos_global, FALSE);
4549 }
4550 }
4551 gSelectMgr->sendMultipleUpdate(UPD_POSITION);
4552 return true;
4553 }
4554};
4555
4556// in order to link, all objects must have the same owner, and the
4557// agent must have the ability to modify all of the objects. However,
4558// we're not answering that question with this method. The question
4559// we're answering is: does the user have a reasonable expectation
4560// that a link operation should work? If so, return true, false
4561// otherwise. this allows the handle_link method to more finely check
4562// the selection and give an error message when the uer has a
4563// reasonable expectation for the link to work, but it will fail.
4564class LLToolsEnableLink : public view_listener_t
4565{
4566 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4567 {
4568 bool new_value = false;
4569 // check if there are at least 2 objects selected, and that the
4570 // user can modify at least one of the selected objects.
4571
4572 // in component mode, can't link
4573 if (gSavedSettings.getBOOL("SelectLinkedSet"))
4574 {
4575 if(gSelectMgr->selectGetAllRootsValid() && gSelectMgr->getRootObjectCount() >= 2)
4576 {
4577 for(LLViewerObject* object = gSelectMgr->getFirstRootObject();
4578 object != NULL;
4579 object = gSelectMgr->getNextRootObject())
4580 {
4581 if(object->permModify())
4582 {
4583 new_value = true;
4584 break;
4585 }
4586 }
4587 }
4588 }
4589 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4590 return true;
4591 }
4592};
4593
4594class LLToolsLink : public view_listener_t
4595{
4596 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4597 {
4598 if(!gSelectMgr->selectGetAllRootsValid())
4599 {
4600 LLNotifyBox::showXml("UnableToLinkWhileDownloading");
4601 return true;
4602 }
4603
4604 S32 object_count = gSelectMgr->getObjectCount();
4605 if (object_count > MAX_CHILDREN_PER_TASK + 1)
4606 {
4607 LLStringBase<char>::format_map_t args;
4608 args["[COUNT]"] = llformat("%d", object_count);
4609 int max = MAX_CHILDREN_PER_TASK+1;
4610 args["[MAX]"] = llformat("%d", max);
4611 gViewerWindow->alertXml("UnableToLinkObjects", args);
4612 return true;
4613 }
4614
4615 if(gSelectMgr->getRootObjectCount() < 2)
4616 {
4617 gViewerWindow->alertXml("CannotLinkIncompleteSet");
4618 return true;
4619 }
4620 if(!gSelectMgr->selectGetRootsModify())
4621 {
4622 gViewerWindow->alertXml("CannotLinkModify");
4623 return true;
4624 }
4625 LLUUID owner_id;
4626 LLString owner_name;
4627 if(!gSelectMgr->selectGetOwner(owner_id, owner_name))
4628 {
4629 // we don't actually care if you're the owner, but novices are
4630 // the most likely to be stumped by this one, so offer the
4631 // easiest and most likely solution.
4632 gViewerWindow->alertXml("CannotLinkDifferentOwners");
4633 return true;
4634 }
4635 gSelectMgr->sendLink();
4636 return true;
4637 }
4638};
4639
4640class LLToolsEnableUnlink : public view_listener_t
4641{
4642 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4643 {
4644 bool new_value = gSelectMgr->selectGetAllRootsValid() &&
4645 gSelectMgr->getFirstEditableObject() &&
4646 !gSelectMgr->getFirstEditableObject()->isAttachment();
4647 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4648 return true;
4649 }
4650};
4651
4652class LLToolsUnlink : public view_listener_t
4653{
4654 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4655 {
4656 gSelectMgr->sendDelink();
4657 return true;
4658 }
4659};
4660
4661
4662class LLToolsStopAllAnimations : public view_listener_t
4663{
4664 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4665 {
4666 LLVOAvatar* avatarp = gAgent.getAvatarObject();
4667
4668 if (!avatarp) return true;
4669
4670 LLVOAvatar::AnimSourceIterator anim_it = avatarp->mAnimationSources.begin();
4671 for (;anim_it != avatarp->mAnimationSources.end(); ++anim_it)
4672 {
4673 avatarp->stopMotion( anim_it->second, TRUE );
4674 }
4675
4676 avatarp->processAnimationStateChanges();
4677 return true;
4678 }
4679};
4680
4681void handle_hinge(void*)
4682{
4683 gSelectMgr->sendHinge(1);
4684}
4685
4686void handle_ptop(void*)
4687{
4688 gSelectMgr->sendHinge(2);
4689}
4690
4691void handle_lptop(void*)
4692{
4693 gSelectMgr->sendHinge(3);
4694}
4695
4696void handle_wheel(void*)
4697{
4698 gSelectMgr->sendHinge(4);
4699}
4700
4701void handle_dehinge(void*)
4702{
4703 gSelectMgr->sendDehinge();
4704}
4705
4706BOOL enable_dehinge(void*)
4707{
4708 LLViewerObject* obj = gSelectMgr->getFirstEditableObject();
4709 return obj && !obj->isAttachment();
4710}
4711
4712
4713class LLEditEnableCut : public view_listener_t
4714{
4715 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4716 {
4717 bool new_value = gEditMenuHandler && gEditMenuHandler->canCut();
4718 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4719 return true;
4720 }
4721};
4722
4723class LLEditCut : public view_listener_t
4724{
4725 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4726 {
4727 if( gEditMenuHandler )
4728 {
4729 gEditMenuHandler->cut();
4730 }
4731 return true;
4732 }
4733};
4734
4735class LLEditEnableCopy : public view_listener_t
4736{
4737 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4738 {
4739 bool new_value = gEditMenuHandler && gEditMenuHandler->canCopy();
4740 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4741 return true;
4742 }
4743};
4744
4745class LLEditCopy : public view_listener_t
4746{
4747 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4748 {
4749 if( gEditMenuHandler )
4750 {
4751 gEditMenuHandler->copy();
4752 }
4753 return true;
4754 }
4755};
4756
4757class LLEditEnablePaste : public view_listener_t
4758{
4759 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4760 {
4761 bool new_value = gEditMenuHandler && gEditMenuHandler->canPaste();
4762 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4763 return true;
4764 }
4765};
4766
4767class LLEditPaste : public view_listener_t
4768{
4769 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4770 {
4771 if( gEditMenuHandler )
4772 {
4773 gEditMenuHandler->paste();
4774 }
4775 return true;
4776 }
4777};
4778
4779class LLEditEnableDelete : public view_listener_t
4780{
4781 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4782 {
4783 bool new_value = gEditMenuHandler && gEditMenuHandler->canDoDelete();
4784 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4785 return true;
4786 }
4787};
4788
4789class LLEditDelete : public view_listener_t
4790{
4791 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4792 {
4793 // If a text field can do a deletion, it gets precedence over deleting
4794 // an object in the world.
4795 if( gEditMenuHandler && gEditMenuHandler->canDoDelete())
4796 {
4797 gEditMenuHandler->doDelete();
4798 }
4799
4800 // and close any pie/context menus when done
4801 gMenuHolder->hideMenus();
4802
4803 // When deleting an object we may not actually be done
4804 // Keep selection so we know what to delete when confirmation is needed about the delete
4805 gPieObject->hide(TRUE);
4806 return true;
4807 }
4808};
4809
4810class LLObjectEnableDelete : public view_listener_t
4811{
4812 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4813 {
4814 bool new_value =
4815#ifdef HACKED_GODLIKE_VIEWER
4816 TRUE;
4817#else
4818# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
4819 (!gInProductionGrid && gAgent.isGodlike()) ||
4820# endif
4821 (gSelectMgr && gSelectMgr->canDoDelete());
4822#endif
4823 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4824 return true;
4825 }
4826};
4827
4828class LLEditSearch : public view_listener_t
4829{
4830 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4831 {
4832 LLFloaterDirectory::toggleFind(NULL);
4833 return true;
4834 }
4835};
4836
4837class LLObjectDelete : public view_listener_t
4838{
4839 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4840 {
4841 if (gSelectMgr)
4842 {
4843 gSelectMgr->doDelete();
4844 }
4845
4846 // and close any pie/context menus when done
4847 gMenuHolder->hideMenus();
4848
4849 // When deleting an object we may not actually be done
4850 // Keep selection so we know what to delete when confirmation is needed about the delete
4851 gPieObject->hide(TRUE);
4852 return true;
4853 }
4854};
4855
4856void handle_force_delete(void*)
4857{
4858 gSelectMgr->selectForceDelete();
4859}
4860
4861class LLViewEnableLastChatter : public view_listener_t
4862{
4863 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4864 {
4865 // *TODO: add check that last chatter is in range
4866 bool new_value = (gAgent.cameraThirdPerson() && gAgent.getLastChatter().notNull());
4867 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4868 return true;
4869 }
4870};
4871
4872class LLEditEnableDeselect : public view_listener_t
4873{
4874 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4875 {
4876 bool new_value = gEditMenuHandler && gEditMenuHandler->canDeselect();
4877 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4878 return true;
4879 }
4880};
4881
4882class LLEditDeselect : public view_listener_t
4883{
4884 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4885 {
4886 if( gEditMenuHandler )
4887 {
4888 gEditMenuHandler->deselect();
4889 }
4890 return true;
4891 }
4892};
4893
4894class LLEditEnableSelectAll : public view_listener_t
4895{
4896 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4897 {
4898 bool new_value = gEditMenuHandler && gEditMenuHandler->canSelectAll();
4899 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4900 return true;
4901 }
4902};
4903
4904
4905class LLEditSelectAll : public view_listener_t
4906{
4907 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4908 {
4909 if( gEditMenuHandler )
4910 {
4911 gEditMenuHandler->selectAll();
4912 }
4913 return true;
4914 }
4915};
4916
4917
4918class LLEditEnableUndo : public view_listener_t
4919{
4920 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4921 {
4922 bool new_value = gEditMenuHandler && gEditMenuHandler->canUndo();
4923 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4924 return true;
4925 }
4926};
4927
4928class LLEditUndo : public view_listener_t
4929{
4930 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4931 {
4932 if( gEditMenuHandler && gEditMenuHandler->canUndo() )
4933 {
4934 gEditMenuHandler->undo();
4935 }
4936 return true;
4937 }
4938};
4939
4940class LLEditEnableRedo : public view_listener_t
4941{
4942 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4943 {
4944 bool new_value = gEditMenuHandler && gEditMenuHandler->canRedo();
4945 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
4946 return true;
4947 }
4948};
4949
4950class LLEditRedo : public view_listener_t
4951{
4952 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
4953 {
4954 if( gEditMenuHandler && gEditMenuHandler->canRedo() )
4955 {
4956 gEditMenuHandler->redo();
4957 }
4958 return true;
4959 }
4960};
4961
4962
4963
4964void print_object_info(void*)
4965{
4966 gSelectMgr->selectionDump();
4967}
4968
4969
4970void show_debug_menus()
4971{
4972 // this can get called at login screen where there is no menu so only toggle it if one exists
4973 if ( gMenuBarView )
4974 {
4975 BOOL debug = gSavedSettings.getBOOL("UseDebugMenus");
4976 gMenuBarView->setItemVisible(CLIENT_MENU_NAME, debug);
4977 gMenuBarView->setItemEnabled(CLIENT_MENU_NAME, debug);
4978 gMenuBarView->setItemVisible(SERVER_MENU_NAME, debug);
4979 gMenuBarView->setItemEnabled(SERVER_MENU_NAME, debug);
4980 //gMenuBarView->setItemVisible(LLString("DebugOptions"), visible);
4981 //gMenuBarView->setItemVisible(LLString(AVI_TOOLS), visible);
4982 };
4983}
4984
4985void toggle_debug_menus(void*)
4986{
4987 BOOL visible = ! gSavedSettings.getBOOL("UseDebugMenus");
4988 gSavedSettings.setBOOL("UseDebugMenus", visible);
4989 show_debug_menus();
4990}
4991
4992
4993void toggle_map( void* user_data )
4994{
4995 // Toggle the item
4996 BOOL checked = gSavedSettings.getBOOL( static_cast<char*>(user_data) );
4997 gSavedSettings.setBOOL( static_cast<char*>(user_data), !checked );
4998 if (checked)
4999 {
5000 gFloaterMap->close();
5001 }
5002 else
5003 {
5004 gFloaterMap->open();
5005 }
5006}
5007
5008/**
5009 char* upload_pick(void* data)
5010
5011 If applicable, brings up a file chooser in which the user selects a file
5012 to upload for a particular task. If the file is valid for the given action,
5013 returns the string to the full path filename, else returns NULL.
5014 Data is the load filter for the type of file as defined in LLFilePicker.
5015**/
5016const char* upload_pick(void* data)
5017{
5018 if( gAgent.cameraMouselook() )
5019 {
5020 gAgent.changeCameraToDefault();
5021 // This doesn't seem necessary. JC
5022 // display();
5023 }
5024
5025 LLFilePicker::ELoadFilter type;
5026 if(data)
5027 {
5028 type = (LLFilePicker::ELoadFilter)((S32)data);
5029 }
5030 else
5031 {
5032 type = LLFilePicker::FFLOAD_ALL;
5033 }
5034
5035 LLFilePicker& picker = LLFilePicker::instance();
5036 if (!picker.getOpenFile(type))
5037 {
5038 llinfos << "Couldn't import objects from file" << llendl;
5039 return NULL;
5040 }
5041
5042 const char* filename = picker.getFirstFile();
5043 const char* ext = strrchr(filename, '.');
5044
5045 //strincmp doesn't like NULL pointers
5046 if (ext == NULL)
5047 {
5048 const char* short_name = strrchr(filename,
5049 *gDirUtilp->getDirDelimiter().c_str());
5050
5051 // No extension
5052 LLStringBase<char>::format_map_t args;
5053 args["[FILE]"] = LLString(short_name + 1);
5054 gViewerWindow->alertXml("NoFileExtension", args);
5055 return NULL;
5056 }
5057 else
5058 {
5059 //so there is an extension
5060 //loop over the valid extensions and compare to see
5061 //if the extension is valid
5062
5063 //now grab the set of valid file extensions
5064 const char* valids = build_extensions_string(type);
5065 std::string valid_extensions = std::string(valids);
5066
5067 BOOL ext_valid = FALSE;
5068
5069 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
5070 boost::char_separator<char> sep(" ");
5071 tokenizer tokens(valid_extensions, sep);
5072 tokenizer::iterator token_iter;
5073
5074 //now loop over all valid file extensions
5075 //and compare them to the extension of the file
5076 //to be uploaded
5077 for( token_iter = tokens.begin();
5078 token_iter != tokens.end() && ext_valid != TRUE;
5079 ++token_iter)
5080 {
5081 const char* cur_token = token_iter->c_str();
5082
5083 if (0 == strnicmp(cur_token, ext, strlen(cur_token)) ||
5084 0 == strnicmp(cur_token, "*.*", strlen(cur_token)))
5085 {
5086 //valid extension
5087 //or the acceptable extension is any
5088 ext_valid = TRUE;
5089 }
5090 }//end for (loop over all tokens)
5091
5092 if (ext_valid == FALSE)
5093 {
5094 //should only get here if the extension exists
5095 //but is invalid
5096 LLStringBase<char>::format_map_t args;
5097 args["[EXTENSION]"] = ext;
5098 args["[VALIDS]"] = valids;
5099 gViewerWindow->alertXml("InvalidFileExtension", args);
5100 return NULL;
5101 }
5102 }//end else (non-null extension)
5103
5104 //valid file extension
5105
5106 //now we check to see
5107 //if the file is actually a valid image/sound/etc.
5108 if (type == LLFilePicker::FFLOAD_WAV)
5109 {
5110 // pre-qualify wavs to make sure the format is acceptable
5111 char error_msg[MAX_STRING];
5112 if (check_for_invalid_wav_formats(filename,error_msg))
5113 {
5114 llinfos << error_msg << ": " << filename << llendl;
5115 LLStringBase<char>::format_map_t args;
5116 args["[FILE]"] = filename;
5117 gViewerWindow->alertXml( error_msg, args );
5118 return NULL;
5119 }
5120 }//end if a wave/sound file
5121
5122
5123 return filename;
5124}
5125
5126void handle_upload_object(void* data)
5127{
5128 const char* filename = upload_pick(data);
5129 if (filename)
5130 {
5131 // start the import
5132 LLFloaterImport* floaterp = new LLFloaterImport(filename);
5133 gUICtrlFactory->buildFloater(floaterp, "floater_import.xml");
5134 }
5135}
5136
5137class LLFileUploadImage : public view_listener_t
5138{
5139 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5140 {
5141 const char* filename = upload_pick((void *)(S32)LLFilePicker::FFLOAD_IMAGE);
5142 if (filename)
5143 {
5144 LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename);
5145 gUICtrlFactory->buildFloater(floaterp, "floater_image_preview.xml");
5146 }
5147 return TRUE;
5148 }
5149};
5150
5151class LLFileUploadSound : public view_listener_t
5152{
5153 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5154 {
5155 const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_WAV));
5156 if (filename)
5157 {
5158 LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
5159 gUICtrlFactory->buildFloater(floaterp, "floater_sound_preview.xml");
5160 }
5161 return true;
5162 }
5163};
5164
5165class LLFileUploadAnim : public view_listener_t
5166{
5167 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5168 {
5169 const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_ANIM));
5170 if (filename)
5171 {
5172 LLFloaterAnimPreview* floaterp = new LLFloaterAnimPreview(filename);
5173 gUICtrlFactory->buildFloater(floaterp, "floater_animation_preview.xml");
5174 }
5175 return true;
5176 }
5177};
5178
5179class LLFileUploadBulk : public view_listener_t
5180{
5181 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5182 {
5183 if( gAgent.cameraMouselook() )
5184 {
5185 gAgent.changeCameraToDefault();
5186 }
5187
5188 // TODO:
5189 // Iterate over all files
5190 // Check extensions for uploadability, cost
5191 // Check user balance for entire cost
5192 // Charge user entire cost
5193 // Loop, uploading
5194 // If an upload fails, refund the user for that one
5195 //
5196 // Also fix single upload to charge first, then refund
5197
5198 LLFilePicker& picker = LLFilePicker::instance();
5199 if (picker.getMultipleOpenFiles())
5200 {
5201 const char* filename = picker.getFirstFile();
5202 const char* name = picker.getDirname();
5203
5204 LLString asset_name = name;
5205 LLString::replaceNonstandardASCII( asset_name, '?' );
5206 LLString::replaceChar(asset_name, '|', '?');
5207 LLString::stripNonprintable(asset_name);
5208 LLString::trim(asset_name);
5209
5210 char* asset_name_str = (char*)asset_name.c_str();
5211 char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists
5212 if( !end_p )
5213 {
5214 end_p = asset_name_str + strlen( asset_name_str );
5215 }
5216
5217 S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
5218
5219 asset_name = asset_name.substr( 0, len );
5220
5221 upload_new_resource(filename, asset_name, asset_name, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); // file
5222 }
5223 else
5224 {
5225 llinfos << "Couldn't import objects from file" << llendl;
5226 }
5227 return true;
5228 }
5229};
5230
5231void upload_error(const char* error_message, const char* label, const std::string filename, const LLStringBase<char>::format_map_t args)
5232{
5233 llwarns << error_message << llendl;
5234 gViewerWindow->alertXml(label, args);
5235 if(remove(filename.c_str()) == -1)
5236 {
5237 lldebugs << "unable to remove temp file" << llendl;
5238 }
5239 LLFilePicker::instance().reset();
5240}
5241
5242class LLFileCloseWindow : public view_listener_t
5243{
5244 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5245 {
5246 LLFloater *top = gFloaterView->getFrontmost();
5247 if (top && top->hasFocus())
5248 {
5249 LLFloater::closeByMenu( top );
5250 }
5251 return true;
5252 }
5253};
5254
5255class LLFileSaveTexture : public view_listener_t
5256{
5257 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5258 {
5259 LLFloater* top = gFloaterView->getFrontmost();
5260 if (top)
5261 {
5262 top->saveAs();
5263 }
5264 return true;
5265 }
5266};
5267
5268class LLFileTakeSnapshot : public view_listener_t
5269{
5270 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5271 {
5272 LLFloaterSnapshot::show(NULL);
5273 return true;
5274 }
5275};
5276
5277class LLFileTakeSnapshotToDisk : public view_listener_t
5278{
5279 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5280 {
5281 LLPointer<LLImageRaw> raw = new LLImageRaw;
5282
5283 S32 width = gViewerWindow->getWindowDisplayWidth();
5284 S32 height = gViewerWindow->getWindowDisplayHeight();
5285
5286 if (gSavedSettings.getBOOL("HighResSnapshot"))
5287 {
5288 width *= 2;
5289 height *= 2;
5290 }
5291
5292 if (gViewerWindow->rawSnapshot(raw,
5293 width,
5294 height,
5295 TRUE,
5296 gSavedSettings.getBOOL("RenderUIInSnapshot"),
5297 FALSE))
5298 {
5299 if (!gQuietSnapshot)
5300 {
5301 gViewerWindow->playSnapshotAnimAndSound();
5302 }
5303 LLImageBase::setSizeOverride(TRUE);
5304 gViewerWindow->saveImageNumbered(raw);
5305 LLImageBase::setSizeOverride(FALSE);
5306 }
5307 return true;
5308 }
5309};
5310
5311class LLFileSaveMovie : public view_listener_t
5312{
5313 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5314 {
5315 LLViewerWindow::saveMovieNumbered(NULL);
5316 return true;
5317 }
5318};
5319
5320class LLFileSetWindowSize : public view_listener_t
5321{
5322 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5323 {
5324 LLString size = userdata.asString();
5325 S32 width, height;
5326 sscanf(size.c_str(), "%d,%d", &width, &height);
5327 LLViewerWindow::movieSize(width, height);
5328 return true;
5329 }
5330};
5331
5332class LLFileQuit : public view_listener_t
5333{
5334 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5335 {
5336 app_request_quit();
5337 return true;
5338 }
5339};
5340
5341void handle_upload(void* data)
5342{
5343 const char* filename = upload_pick(data);
5344 if (filename)
5345 {
5346 LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
5347 gUICtrlFactory->buildFloater(floaterp, "floater_name_description.xml");
5348 }
5349}
5350
5351void handle_compress_image(void*)
5352{
5353 LLFilePicker& picker = LLFilePicker::instance();
5354 if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE))
5355 {
5356 std::string infile(picker.getFirstFile());
5357 std::string outfile = infile + ".j2c";
5358
5359 llinfos << "Input: " << infile << llendl;
5360 llinfos << "Output: " << outfile << llendl;
5361
5362 BOOL success;
5363
5364 success = LLViewerImageList::createUploadFile(infile, outfile, IMG_CODEC_TGA);
5365
5366 if (success)
5367 {
5368 llinfos << "Compression complete" << llendl;
5369 }
5370 else
5371 {
5372 llinfos << "Compression failed: " << LLImageBase::getLastError() << llendl;
5373 }
5374 }
5375}
5376
5377void upload_new_resource(const LLString& src_filename, std::string name,
5378 std::string desc, S32 compression_info,
5379 LLAssetType::EType destination_folder_type,
5380 LLInventoryType::EType inv_type,
5381 U32 next_owner_perm,
5382 const LLString& display_name,
5383 LLAssetStorage::LLStoreAssetCallback callback,
5384 void *userdata)
5385{
5386 // Generate the temporary UUID.
5387 LLString filename = gDirUtilp->getTempFilename();
5388 LLTransactionID tid;
5389 LLAssetID uuid;
5390
5391 LLStringBase<char>::format_map_t args;
5392
5393 LLString ext = src_filename.substr(src_filename.find_last_of('.'));
5394 LLAssetType::EType asset_type = LLAssetType::AT_NONE;
5395 char error_message[MAX_STRING];
5396 error_message[0] = '\0';
5397 LLString temp_str;
5398
5399 BOOL error = FALSE;
5400
5401 if (ext.empty())
5402 {
5403 LLString::size_type offset = filename.find_last_of(gDirUtilp->getDirDelimiter());
5404 if (offset != LLString::npos)
5405 offset++;
5406 LLString short_name = filename.substr(offset);
5407
5408 // No extension
5409 sprintf(error_message,
5410 "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension",
5411 short_name.c_str());
5412 args["[FILE]"] = short_name;
5413 upload_error(error_message, "NofileExtension", filename, args);
5414 return;
5415 }
5416 else if( LLString::compareInsensitive(ext.c_str(),".bmp") == 0 )
5417 {
5418 asset_type = LLAssetType::AT_TEXTURE;
5419 if (!LLViewerImageList::createUploadFile(src_filename,
5420 filename,
5421 IMG_CODEC_BMP ))
5422 {
5423 sprintf(error_message, "Problem with file %s:\n\n%s\n",
5424 src_filename.c_str(), LLImageBase::getLastError().c_str());
5425 args["[FILE]"] = src_filename;
5426 args["[ERROR]"] = LLImageBase::getLastError();
5427 upload_error(error_message, "ProblemWithFile", filename, args);
5428 return;
5429 }
5430 }
5431 else if( LLString::compareInsensitive(ext.c_str(),".tga") == 0 )
5432 {
5433 asset_type = LLAssetType::AT_TEXTURE;
5434 if (!LLViewerImageList::createUploadFile(src_filename,
5435 filename,
5436 IMG_CODEC_TGA ))
5437 {
5438 sprintf(error_message, "Problem with file %s:\n\n%s\n",
5439 src_filename.c_str(), LLImageBase::getLastError().c_str());
5440 args["[FILE]"] = src_filename;
5441 args["[ERROR]"] = LLImageBase::getLastError();
5442 upload_error(error_message, "ProblemWithFile", filename, args);
5443 return;
5444 }
5445 }
5446 else if( LLString::compareInsensitive(ext.c_str(),".jpg") == 0 || LLString::compareInsensitive(ext.c_str(),".jpeg") == 0)
5447 {
5448 asset_type = LLAssetType::AT_TEXTURE;
5449 if (!LLViewerImageList::createUploadFile(src_filename,
5450 filename,
5451 IMG_CODEC_JPEG ))
5452 {
5453 sprintf(error_message, "Problem with file %s:\n\n%s\n",
5454 src_filename.c_str(), LLImageBase::getLastError().c_str());
5455 args["[FILE]"] = src_filename;
5456 args["[ERROR]"] = LLImageBase::getLastError();
5457 upload_error(error_message, "ProblemWithFile", filename, args);
5458 return;
5459 }
5460 }
5461 else if(LLString::compareInsensitive(ext.c_str(),".wav") == 0)
5462 {
5463 asset_type = LLAssetType::AT_SOUND; // tag it as audio
5464 S32 encode_result = 0;
5465
5466 S32 bitrate = 128;
5467
5468 if (compression_info)
5469 {
5470 bitrate = compression_info;
5471 }
5472 llinfos << "Attempting to encode wav as an ogg file at " << bitrate << "kbps" << llendl;
5473
5474 encode_result = encode_vorbis_file_at(src_filename.c_str(), filename.c_str(), bitrate*1000);
5475
5476 if (LLVORBISENC_NOERR != encode_result)
5477 {
5478 switch(encode_result)
5479 {
5480 case LLVORBISENC_DEST_OPEN_ERR:
5481 sprintf(error_message, "Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str());
5482 args["[FILE]"] = filename;
5483 upload_error(error_message, "CannotOpenTemporarySoundFile", filename, args);
5484 break;
5485
5486 default:
5487 sprintf(error_message, "Unknown vorbis encode failure on: %s\n", src_filename.c_str());
5488 args["[FILE]"] = src_filename;
5489 upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args);
5490 break;
5491 }
5492 return;
5493 }
5494 }
5495 else if(LLString::compareInsensitive(ext.c_str(),".tmp") == 0)
5496 {
5497 // This is a generic .lin resource file
5498 asset_type = LLAssetType::AT_OBJECT;
5499 FILE *in = LLFile::fopen(src_filename.c_str(), "rb");
5500 if (in)
5501 {
5502 // read in the file header
5503 char buf[16384];
5504 S32 read;
5505 S32 version;
5506 if (fscanf(in, "LindenResource\nversion %d\n", &version))
5507 {
5508 if (2 == version)
5509 {
5510 char label[MAX_STRING];
5511 char value[MAX_STRING];
5512 S32 tokens_read;
5513 while (fgets(buf, 1024, in))
5514 {
5515 label[0] = '\0';
5516 value[0] = '\0';
5517 tokens_read = sscanf(buf, "%s %s\n", label, value);
5518
5519 llinfos << "got: " << label << " = " << value
5520 << llendl;
5521
5522 if (EOF == tokens_read)
5523 {
5524 fclose(in);
5525 sprintf(error_message, "corrupt resource file: %s", src_filename.c_str());
5526 args["[FILE]"] = src_filename;
5527 upload_error(error_message, "CorruptResourceFile", filename, args);
5528 return;
5529 }
5530
5531 if (2 == tokens_read)
5532 {
5533 if (! strcmp("type", label))
5534 {
5535 asset_type = (LLAssetType::EType)(atoi(value));
5536 }
5537 }
5538 else
5539 {
5540 if (! strcmp("_DATA_", label))
5541 {
5542 // below is the data section
5543 break;
5544 }
5545 }
5546 // other values are currently discarded
5547 }
5548
5549 }
5550 else
5551 {
5552 fclose(in);
5553 sprintf(error_message, "unknown linden resource file version in file: %s", src_filename.c_str());
5554 args["[FILE]"] = src_filename;
5555 upload_error(error_message, "UnknownResourceFileVersion", filename, args);
5556 return;
5557 }
5558 }
5559 else
5560 {
5561 // this is an original binary formatted .lin file
5562 // start over at the beginning of the file
5563 fseek(in, 0, SEEK_SET);
5564
5565 const S32 MAX_ASSET_DESCRIPTION_LENGTH = 256;
5566 const S32 MAX_ASSET_NAME_LENGTH = 64;
5567 S32 header_size = 34 + MAX_ASSET_DESCRIPTION_LENGTH + MAX_ASSET_NAME_LENGTH;
5568 S16 type_num;
5569
5570 // read in and throw out most of the header except for the type
5571 fread(buf, header_size, 1, in);
5572 memcpy(&type_num, buf + 16, sizeof(S16));
5573 asset_type = (LLAssetType::EType)type_num;
5574 }
5575
5576 // copy the file's data segment into another file for uploading
5577 FILE *out = LLFile::fopen(filename.c_str(), "wb");
5578 if (out)
5579 {
5580 while((read = fread(buf, 1, 16384, in)))
5581 {
5582 fwrite(buf, 1, read, out);
5583 }
5584 fclose(out);
5585 }
5586 else
5587 {
5588 fclose(in);
5589 sprintf(error_message, "Unable to create output file: %s", filename.c_str());
5590 args["[FILE]"] = filename;
5591 upload_error(error_message, "UnableToCreateOutputFile", filename, args);
5592 return;
5593 }
5594
5595 fclose(in);
5596 }
5597 else
5598 {
5599 llinfos << "Couldn't open .lin file " << src_filename << llendl;
5600 }
5601 }
5602 else if (LLString::compareInsensitive(ext.c_str(),".bvh") == 0)
5603 {
5604 sprintf(error_message, "We do not currently support bulk upload of animation files\n");
5605 upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args);
5606 return;
5607 }
5608 else
5609 {
5610 // Unknown extension
5611 sprintf(error_message, "Unknown file extension %s\nExpected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh", ext.c_str());
5612 error = TRUE;;
5613 }
5614
5615 // gen a new transaction ID for this asset
5616 tid.generate();
5617
5618 if (!error)
5619 {
5620 uuid = tid.makeAssetID(gAgent.getSecureSessionID());
5621 // copy this file into the vfs for upload
5622 S32 file_size;
5623 apr_file_t* fp = ll_apr_file_open(filename, LL_APR_RB, &file_size);
5624 if (fp)
5625 {
5626 LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE);
5627
5628 file.setMaxSize(file_size);
5629
5630 const S32 buf_size = 65536;
5631 U8 copy_buf[buf_size];
5632 while ((file_size = ll_apr_file_read(fp, copy_buf, buf_size)))
5633 {
5634 file.write(copy_buf, file_size);
5635 }
5636 apr_file_close(fp);
5637 }
5638 else
5639 {
5640 sprintf(error_message, "Unable to access output file: %s", filename.c_str());
5641 error = TRUE;
5642 }
5643 }
5644
5645 if (!error)
5646 {
5647 LLString t_disp_name = display_name;
5648 if (t_disp_name.empty())
5649 {
5650 t_disp_name = src_filename;
5651 }
5652 upload_new_resource(tid, asset_type, name, desc, compression_info, // tid
5653 destination_folder_type, inv_type, next_owner_perm,
5654 display_name, callback, userdata);
5655 }
5656 else
5657 {
5658 llwarns << error_message << llendl;
5659 LLStringBase<char>::format_map_t args;
5660 args["[ERROR_MESSAGE]"] = error_message;
5661 gViewerWindow->alertXml("ErrorMessage", args);
5662 if(LLFile::remove(filename.c_str()) == -1)
5663 {
5664 lldebugs << "unable to remove temp file" << llendl;
5665 }
5666 LLFilePicker::instance().reset();
5667 }
5668}
5669
5670void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type,
5671 std::string name,
5672 std::string desc, S32 compression_info,
5673 LLAssetType::EType destination_folder_type,
5674 LLInventoryType::EType inv_type,
5675 U32 next_owner_perm,
5676 const LLString& display_name,
5677 LLAssetStorage::LLStoreAssetCallback callback,
5678 void *userdata)
5679{
5680 LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID());
5681
5682 if( LLAssetType::AT_SOUND == asset_type )
5683 {
5684 gViewerStats->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT );
5685 }
5686 else
5687 if( LLAssetType::AT_TEXTURE == asset_type )
5688 {
5689 gViewerStats->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
5690 }
5691 else
5692 if( LLAssetType::AT_ANIMATION == asset_type)
5693 {
5694 gViewerStats->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT );
5695 }
5696
5697 if(LLInventoryType::IT_NONE == inv_type)
5698 {
5699 inv_type = LLInventoryType::defaultForAssetType(asset_type);
5700 }
5701 LLString::stripNonprintable(name);
5702 LLString::stripNonprintable(desc);
5703 if(name.empty())
5704 {
5705 name = "(No Name)";
5706 }
5707 if(desc.empty())
5708 {
5709 desc = "(No Description)";
5710 }
5711
5712 // At this point, we're ready for the upload.
5713 LLString upload_message = "Uploading...\n\n";
5714 upload_message.append(display_name);
5715 LLUploadDialog::modalUploadDialog(upload_message);
5716
5717 llinfos << "*** Uploading: " << llendl;
5718 llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl;
5719 llinfos << "UUID: " << uuid << llendl;
5720 llinfos << "Name: " << name << llendl;
5721 llinfos << "Desc: " << desc << llendl;
5722 lldebugs << "Folder: " << gInventory.findCategoryUUIDForType(destination_folder_type) << llendl;
5723 lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl;
5724 std::string url = gAgent.getRegion()->getCapability("NewAgentInventory");
5725 if (!url.empty())
5726 {
5727 llinfos << "New Agent Inventory via capability" << llendl;
5728 LLSD body;
5729 body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type);
5730 body["asset_type"] = LLAssetType::lookup(asset_type);
5731 body["inventory_type"] = LLInventoryType::lookup(inv_type);
5732 body["name"] = name;
5733 body["description"] = desc;
5734
5735 std::ostringstream llsdxml;
5736 LLSDSerialize::toXML(body, llsdxml);
5737 lldebugs << "posting body to capability: " << llsdxml.str() << llendl;
5738 LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(uuid, body));
5739 }
5740 else
5741 {
5742 llinfos << "NewAgentInventory capability not found, new agent inventory via asset system." << llendl;
5743 // check for adequate funds
5744 // TODO: do this check on the sim
5745 if (LLAssetType::AT_SOUND == asset_type ||
5746 LLAssetType::AT_TEXTURE == asset_type ||
5747 LLAssetType::AT_ANIMATION == asset_type)
5748 {
5749 S32 upload_cost = gGlobalEconomy->getPriceUpload();
5750 S32 balance = gStatusBar->getBalance();
5751 if (balance < upload_cost)
5752 {
5753 // insufficient funds, bail on this upload
5754 LLFloaterBuyCurrency::buyCurrency("Uploading costs", upload_cost);
5755 return;
5756 }
5757 }
5758
5759 LLResourceData* data = new LLResourceData;
5760 data->mAssetInfo.mTransactionID = tid;
5761 data->mAssetInfo.mUuid = uuid;
5762 data->mAssetInfo.mType = asset_type;
5763 data->mAssetInfo.mCreatorID = gAgentID;
5764 data->mInventoryType = inv_type;
5765 data->mNextOwnerPerm = next_owner_perm;
5766 data->mUserData = userdata;
5767 data->mAssetInfo.setName(name);
5768 data->mAssetInfo.setDescription(desc);
5769 data->mPreferredLocation = destination_folder_type;
5770
5771 LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback;
5772 if (callback)
5773 {
5774 asset_callback = callback;
5775 }
5776 gAssetStorage->storeAssetData(data->mAssetInfo.mTransactionID, data->mAssetInfo.mType,
5777 asset_callback,
5778 (void*)data,
5779 FALSE);
5780 }
5781}
5782
5783void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result) // StoreAssetData callback (fixed)
5784{
5785 LLResourceData* data = (LLResourceData*)user_data;
5786 //LLAssetType::EType pref_loc = data->mPreferredLocation;
5787 BOOL is_balance_sufficient = TRUE;
5788 if(result >= 0)
5789 {
5790 LLAssetType::EType dest_loc = (data->mPreferredLocation == LLAssetType::AT_NONE) ? data->mAssetInfo.mType : data->mPreferredLocation;
5791
5792 if (LLAssetType::AT_SOUND == data->mAssetInfo.mType ||
5793 LLAssetType::AT_TEXTURE == data->mAssetInfo.mType ||
5794 LLAssetType::AT_ANIMATION == data->mAssetInfo.mType)
5795 {
5796 // Charge the user for the upload.
5797 LLViewerRegion* region = gAgent.getRegion();
5798 S32 upload_cost = gGlobalEconomy->getPriceUpload();
5799
5800 if(!(can_afford_transaction(upload_cost)))
5801 {
5802 LLFloaterBuyCurrency::buyCurrency(
5803 llformat("Uploading %s costs",
5804 data->mAssetInfo.getName().c_str()),
5805 upload_cost);
5806 is_balance_sufficient = FALSE;
5807 }
5808 else if(region)
5809 {
5810 // Charge user for upload
5811 gStatusBar->debitBalance(upload_cost);
5812
5813 LLMessageSystem* msg = gMessageSystem;
5814 msg->newMessageFast(_PREHASH_MoneyTransferRequest);
5815 msg->nextBlockFast(_PREHASH_AgentData);
5816 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
5817 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
5818 msg->nextBlockFast(_PREHASH_MoneyData);
5819 msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID());
5820 msg->addUUIDFast(_PREHASH_DestID, LLUUID::null);
5821 msg->addU8("Flags", 0);
5822 msg->addS32Fast(_PREHASH_Amount, upload_cost);
5823 msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY);
5824 msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY);
5825 msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE);
5826 msg->addStringFast(_PREHASH_Description, NULL);
5827 msg->sendReliable(region->getHost());
5828 }
5829 }
5830
5831 if(is_balance_sufficient)
5832 {
5833 // Actually add the upload to inventory
5834 llinfos << "Adding " << uuid << " to inventory." << llendl;
5835 LLUUID folder_id(gInventory.findCategoryUUIDForType(dest_loc));
5836 if(folder_id.notNull())
5837 {
5838 U32 next_owner_perm = data->mNextOwnerPerm;
5839 if(PERM_NONE == next_owner_perm)
5840 {
5841 next_owner_perm = PERM_MOVE | PERM_TRANSFER;
5842 }
5843 create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
5844 folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(),
5845 data->mAssetInfo.getDescription(), data->mAssetInfo.mType,
5846 data->mInventoryType, NOT_WEARABLE, next_owner_perm,
5847 LLPointer<LLInventoryCallback>(NULL));
5848 }
5849 else
5850 {
5851 llwarns << "Can't find a folder to put it in" << llendl;
5852 }
5853 }
5854 }
5855 else // if(result >= 0)
5856 {
5857 LLStringBase<char>::format_map_t args;
5858 args["[FILE]"] = LLInventoryType::lookupHumanReadable(data->mInventoryType);
5859 args["[REASON]"] = LLString(LLAssetStorage::getErrorString(result));
5860 gViewerWindow->alertXml("CannotUploadReason", args);
5861 }
5862
5863 LLUploadDialog::modalUploadFinished();
5864 delete data;
5865
5866 // *NOTE: This is a pretty big hack. What this does is check the
5867 // file picker if there are any more pending uploads. If so,
5868 // upload that file.
5869 const char* next_file = LLFilePicker::instance().getNextFile();
5870 if(is_balance_sufficient && next_file)
5871 {
5872 const char* name = LLFilePicker::instance().getDirname();
5873
5874 LLString asset_name = name;
5875 LLString::replaceNonstandardASCII( asset_name, '?' );
5876 LLString::replaceChar(asset_name, '|', '?');
5877 LLString::stripNonprintable(asset_name);
5878 LLString::trim(asset_name);
5879
5880 char* asset_name_str = (char*)asset_name.c_str();
5881 char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists
5882 if( !end_p )
5883 {
5884 end_p = asset_name_str + strlen( asset_name_str );
5885 }
5886
5887 S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
5888
5889 asset_name = asset_name.substr( 0, len );
5890
5891 upload_new_resource(next_file, asset_name, asset_name, // file
5892 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE);
5893 }
5894}
5895
5896LLUUID gExporterRequestID;
5897LLString gExportDirectory;
5898
5899LLUploadDialog *gExportDialog = NULL;
5900
5901void handle_export_selected( void * )
5902{
5903 if (gSelectMgr->isEmpty())
5904 {
5905 return;
5906 }
5907 llinfos << "Exporting selected objects:" << llendl;
5908 LLViewerObject *object = gSelectMgr->getFirstRootObject();
5909
5910 gExporterRequestID.generate();
5911 gExportDirectory = "";
5912
5913 LLMessageSystem* msg = gMessageSystem;
5914 msg->newMessageFast(_PREHASH_ObjectExportSelected);
5915 msg->nextBlockFast(_PREHASH_AgentData);
5916 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
5917 msg->addUUIDFast(_PREHASH_RequestID, gExporterRequestID);
5918 msg->addS16Fast(_PREHASH_VolumeDetail, 4);
5919
5920 for (; object != NULL; object = gSelectMgr->getNextRootObject())
5921 {
5922 msg->nextBlockFast(_PREHASH_ObjectData);
5923 msg->addUUIDFast(_PREHASH_ObjectID, object->getID());
5924 llinfos << "Object: " << object->getID() << llendl;
5925 }
5926 msg->sendReliable(gAgent.getRegion()->getHost());
5927
5928 gExportDialog = LLUploadDialog::modalUploadDialog("Exporting selected objects...");
5929}
5930
5931BOOL menu_check_build_tool( void* user_data )
5932{
5933 S32 index = (S32) user_data;
5934 return gCurrentToolset->isToolSelected( index );
5935}
5936
5937void handle_reload_settings(void*)
5938{
5939 gSavedSettings.resetToDefaults();
5940 gSavedSettings.loadFromFile(gSettingsFileName, TRUE);
5941
5942 llinfos << "Loading colors from colors.xml" << llendl;
5943 std::string color_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"colors.xml");
5944 gColors.resetToDefaults();
5945 gColors.loadFromFile(color_file, FALSE, TYPE_COL4U);
5946}
5947
5948class LLWorldSetHomeLocation : public view_listener_t
5949{
5950 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5951 {
5952 // we just send the message and let the server check for failure cases
5953 // server will echo back a "Home position set." alert if it succeeds
5954 // and the home location screencapture happens when that alert is recieved
5955 gAgent.setStartPosition(START_LOCATION_ID_HOME);
5956 return true;
5957 }
5958};
5959
5960class LLWorldTeleportHome : public view_listener_t
5961{
5962 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5963 {
5964 gAgent.teleportHome();
5965 return true;
5966 }
5967};
5968
5969class LLWorldAlwaysRun : public view_listener_t
5970{
5971 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5972 {
5973 if (gAgent.getAlwaysRun())
5974 {
5975 gAgent.clearAlwaysRun();
5976 }
5977 else
5978 {
5979 gAgent.setAlwaysRun();
5980 }
5981 LLMessageSystem *msg = gMessageSystem;
5982
5983
5984 msg->newMessageFast(_PREHASH_SetAlwaysRun);
5985 msg->nextBlockFast(_PREHASH_AgentData);
5986 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
5987 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
5988 msg->addBOOLFast(_PREHASH_AlwaysRun, gAgent.getAlwaysRun() );
5989 gAgent.sendReliableMessage();
5990 return true;
5991 }
5992};
5993
5994class LLWorldCheckAlwaysRun : public view_listener_t
5995{
5996 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5997 {
5998 bool new_value = gAgent.getAlwaysRun();
5999 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
6000 return true;
6001 }
6002};
6003
6004class LLWorldSetAway : public view_listener_t
6005{
6006 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6007 {
6008 if (gAgent.getAFK())
6009 {
6010 gAgent.clearAFK();
6011 }
6012 else
6013 {
6014 gAgent.setAFK();
6015 }
6016 return true;
6017 }
6018};
6019
6020class LLWorldSetBusy : public view_listener_t
6021{
6022 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6023 {
6024 if (gAgent.getBusy())
6025 {
6026 gAgent.clearBusy();
6027 }
6028 else
6029 {
6030 gAgent.setBusy();
6031 gViewerWindow->alertXml("BusyModeSet");
6032 }
6033 return true;
6034 }
6035};
6036
6037
6038class LLWorldCreateLandmark : public view_listener_t
6039{
6040 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6041 {
6042 LLViewerRegion* agent_region = gAgent.getRegion();
6043 if(!agent_region)
6044 {
6045 llwarns << "No agent region" << llendl;
6046 return true;
6047 }
6048 LLParcel* agent_parcel = gParcelMgr->getAgentParcel();
6049 if (!agent_parcel)
6050 {
6051 llwarns << "No agent parcel" << llendl;
6052 return true;
6053 }
6054 if (!agent_parcel->getAllowLandmark()
6055 && !LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
6056 {
6057 gViewerWindow->alertXml("CannotCreateLandmarkNotOwner");
6058 return true;
6059 }
6060
6061 LLUUID folder_id;
6062 folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_LANDMARK);
6063 std::string pos_string;
6064 gAgent.buildLocationString(pos_string);
6065
6066 create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
6067 folder_id, LLTransactionID::tnull,
6068 pos_string, pos_string, // name, desc
6069 LLAssetType::AT_LANDMARK,
6070 LLInventoryType::IT_LANDMARK,
6071 NOT_WEARABLE, PERM_ALL,
6072 NULL);
6073 return true;
6074 }
6075};
6076
6077class LLToolsLookAtSelection : public view_listener_t
6078{
6079 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6080 {
6081 const F32 PADDING_FACTOR = 2.f;
6082 BOOL zoom = (userdata.asString() == "zoom");
6083 if (!gSelectMgr->isEmpty())
6084 {
6085 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
6086
6087 LLBBox selection_bbox = gSelectMgr->getBBoxOfSelection();
6088 F32 angle_of_view = llmax(0.1f, gCamera->getAspect() > 1.f ? gCamera->getView() * gCamera->getAspect() : gCamera->getView());
6089 F32 distance = selection_bbox.getExtentLocal().magVec() * PADDING_FACTOR / atan(angle_of_view);
6090
6091 LLVector3 obj_to_cam = gCamera->getOrigin() - selection_bbox.getCenterAgent();
6092 obj_to_cam.normVec();
6093
6094 if (zoom)
6095 {
6096 gAgent.setCameraPosAndFocusGlobal(gSelectMgr->getSelectionCenterGlobal() + LLVector3d(obj_to_cam * distance), gSelectMgr->getSelectionCenterGlobal(), gSelectMgr->getFirstObject()->mID );
6097 }
6098 else
6099 {
6100 gAgent.setFocusGlobal( gSelectMgr->getSelectionCenterGlobal(), gSelectMgr->getFirstObject()->mID );
6101 }
6102 }
6103 return true;
6104 }
6105};
6106
6107/*
6108void handle_reset_rotation(void*)
6109{
6110 gSelectMgr->selectionResetRotation();
6111
6112 dialog_refresh_all();
6113}
6114*/
6115
6116class LLAvatarAddFriend : public view_listener_t
6117{
6118 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6119 {
6120 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
6121 if(avatar && !is_agent_friend(avatar->getID()))
6122 {
6123 request_friendship(avatar->getID());
6124 }
6125 gSelectMgr->deselectTransient();
6126 return true;
6127 }
6128};
6129
6130void complete_give_money(S32 option, void* user_data)
6131{
6132 if (option == 0)
6133 {
6134 gAgent.clearBusy();
6135 }
6136
6137 LLUUID* object_id = (LLUUID*)user_data;
6138
6139 LLViewerObject* object = gObjectList.findObject(*object_id);
6140 if (object)
6141 {
6142 if (object->isAvatar())
6143 {
6144 const BOOL is_group = FALSE;
6145 LLFloaterPay::payDirectly(&give_money,
6146 *object_id,
6147 is_group);
6148 }
6149 else
6150 {
6151 LLFloaterPay::payViaObject(&give_money, *object_id);
6152 }
6153 }
6154
6155 delete object_id;
6156}
6157
6158bool handle_give_money_dialog()
6159{
6160 LLViewerObject *objectp = gViewerWindow->lastObjectHit();
6161 LLUUID* object_id = new LLUUID();
6162
6163 // Show avatar's name if paying attachment
6164 if (objectp && objectp->isAttachment())
6165 {
6166 while (objectp && !objectp->isAvatar())
6167 {
6168 objectp = (LLViewerObject*)objectp->getParent();
6169 }
6170 }
6171
6172 if (objectp)
6173 {
6174 *object_id = objectp->getID();
6175 }
6176
6177 if (gAgent.getBusy())
6178 {
6179 // warn users of being in busy mode during a transaction
6180 gViewerWindow->alertXml("BusyModePay", complete_give_money, object_id);
6181 }
6182 else
6183 {
6184 complete_give_money(1, object_id);
6185 }
6186 return true;
6187}
6188
6189class LLPayObject : public view_listener_t
6190{
6191 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6192 {
6193 return handle_give_money_dialog();
6194 }
6195};
6196
6197class LLEnablePayObject : public view_listener_t
6198{
6199 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6200 {
6201 LLVOAvatar* avatar = find_avatar_from_object(gViewerWindow->lastObjectHit());
6202 bool new_value = (avatar != NULL);
6203 if (!new_value)
6204 {
6205 LLViewerObject* object = gViewerWindow->lastObjectHit();
6206 if( object )
6207 {
6208 LLViewerObject *parent = (LLViewerObject *)object->getParent();
6209 if((object->flagTakesMoney()) || (parent && parent->flagTakesMoney()))
6210 {
6211 new_value = true;
6212 }
6213 }
6214 }
6215 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
6216 return true;
6217 }
6218};
6219
6220class LLObjectEnableSitOrStand : public view_listener_t
6221{
6222 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6223 {
6224 bool new_value = false;
6225 LLViewerObject* dest_object = NULL;
6226 if(dest_object = gObjectList.findObject(gLastHitObjectID))
6227 {
6228 if(dest_object->getPCode() == LL_PCODE_VOLUME)
6229 {
6230 new_value = true;
6231 }
6232 }
6233 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
6234
6235 // Update label
6236 LLString label;
6237 LLString sit_text;
6238 LLString stand_text;
6239 LLString param = userdata["data"].asString();
6240 LLString::size_type offset = param.find(",");
6241 if (offset != param.npos)
6242 {
6243 sit_text = param.substr(0, offset);
6244 stand_text = param.substr(offset+1);
6245 }
6246 if (sitting_on_selection())
6247 {
6248 label = stand_text;
6249 }
6250 else
6251 {
6252 LLSelectNode* node = gSelectMgr->getFirstRootNode();
6253 if (node && node->mValid && !node->mSitName.empty())
6254 {
6255 label.assign(node->mSitName);
6256 }
6257 else
6258 {
6259 label = sit_text;
6260 }
6261 }
6262 gMenuHolder->childSetText("Object Sit", label);
6263
6264 return true;
6265 }
6266};
6267
6268void edit_ui(void*)
6269{
6270 LLFloater::setEditModeEnabled(!LLFloater::getEditModeEnabled());
6271}
6272
6273void dump_select_mgr(void*)
6274{
6275 gSelectMgr->dump();
6276}
6277
6278void dump_volume_mgr(void*)
6279{
6280 gVolumeMgr->dump();
6281}
6282
6283void dump_inventory(void*)
6284{
6285 gInventory.dumpInventory();
6286}
6287
6288
6289void handle_first_tool(void*)
6290{
6291 gCurrentToolset->selectFirstTool();
6292}
6293
6294
6295void handle_next_tool(void*)
6296{
6297 gCurrentToolset->selectNextTool();
6298}
6299
6300
6301void handle_previous_tool(void*)
6302{
6303 gCurrentToolset->selectPrevTool();
6304}
6305
6306
6307// forcibly unlock an object
6308void handle_force_unlock(void*)
6309{
6310 // First, make it public.
6311 gSelectMgr->sendOwner(LLUUID::null, LLUUID::null, TRUE);
6312
6313 // Second, lie to the viewer and mark it editable and unowned
6314 LLViewerObject* object;
6315 for (object = gSelectMgr->getFirstObject(); object; object = gSelectMgr->getNextObject() )
6316 {
6317 object->mFlags |= FLAGS_OBJECT_MOVE;
6318 object->mFlags |= FLAGS_OBJECT_MODIFY;
6319 object->mFlags |= FLAGS_OBJECT_COPY;
6320
6321 object->mFlags &= ~FLAGS_OBJECT_ANY_OWNER;
6322 object->mFlags &= ~FLAGS_OBJECT_YOU_OWNER;
6323 }
6324}
6325
6326// Fullscreen debug stuff
6327void handle_fullscreen_debug(void*)
6328{
6329 llinfos << "Width " << gViewerWindow->getWindowWidth() << " Height " << gViewerWindow->getWindowHeight() << llendl;
6330 llinfos << "mouse_x_from_center(100) " << mouse_x_from_center(100) << " y " << mouse_y_from_center(100) << llendl;
6331}
6332
6333void handle_crash(void*)
6334{
6335 llerrs << "This is an llerror" << llendl;
6336}
6337
6338class LLWorldForceSun : public view_listener_t
6339{
6340 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6341 {
6342 LLString tod = userdata.asString();
6343 LLVector3 sun_direction;
6344 if (tod == "sunrise")
6345 {
6346 sun_direction.setVec(1.0f, 0.f, 0.2f);
6347 }
6348 else if (tod == "noon")
6349 {
6350 sun_direction.setVec(0.0f, 0.3f, 1.0f);
6351 }
6352 else if (tod == "sunset")
6353 {
6354 sun_direction.setVec(-1.0f, 0.f, 0.2f);
6355 }
6356 else if (tod == "midnight")
6357 {
6358 sun_direction.setVec(0.0f, 0.3f, -1.0f);
6359 }
6360 else
6361 {
6362 gSky.setOverrideSun(FALSE);
6363 return true;
6364 }
6365 sun_direction.normVec();
6366 gSky.setOverrideSun(TRUE);
6367 gSky.setSunDirection( sun_direction, LLVector3(0.f, 0.f, 0.f));
6368 return true;
6369 }
6370};
6371
6372void handle_dump_followcam(void*)
6373{
6374 LLFollowCamMgr::dump();
6375}
6376
6377void handle_viewer_enable_circuit_log(void*)
6378{
6379 llinfos << "Showing circuit information every " << gMessageSystem->mCircuitPrintFreq << " seconds" << llendl;
6380 gErrorStream.setLevel( LLErrorStream::DEBUG );
6381 gErrorStream.setDebugFlag( LLERR_CIRCUIT_INFO );
6382 // and dump stuff out immediately
6383 gMessageSystem->dumpCircuitInfo();
6384}
6385
6386void handle_viewer_disable_circuit_log(void*)
6387{
6388 llinfos << "Hiding circuit information" << llendl;
6389#if !LL_DEBUG
6390 gErrorStream.setLevel( LLErrorStream::INFO );
6391#endif
6392 gErrorStream.clearDebugFlag( LLERR_CIRCUIT_INFO );
6393}
6394
6395void handle_viewer_enable_message_log(void*)
6396{
6397 gMessageSystem->startLogging();
6398}
6399
6400void handle_viewer_disable_message_log(void*)
6401{
6402 gMessageSystem->stopLogging();
6403}
6404
6405// TomY TODO: Move!
6406class LLShowFloater : public view_listener_t
6407{
6408 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6409 {
6410 LLString floater_name = userdata.asString();
6411 if (floater_name == "gestures")
6412 {
6413 LLFloaterGesture::toggleVisibility();
6414 }
6415 else if (floater_name == "appearance")
6416 {
6417 if (gAgent.getWearablesLoaded())
6418 {
6419 gAgent.changeCameraToCustomizeAvatar();
6420 }
6421 }
6422 else if (floater_name == "friends")
6423 {
6424 LLFloaterFriends::toggle(NULL);
6425 }
6426 else if (floater_name == "preferences")
6427 {
6428 LLFloaterPreference::show(NULL);
6429 }
6430 else if (floater_name == "toolbar")
6431 {
6432 LLToolBar::toggle(NULL);
6433 }
6434 else if (floater_name == "chat history")
6435 {
6436 LLFloaterChat::toggle(NULL);
6437 }
6438 else if (floater_name == "im")
6439 {
6440 LLToolBar::onClickIM(NULL);
6441 }
6442 else if (floater_name == "inventory")
6443 {
6444 LLInventoryView::toggleVisibility(NULL);
6445 }
6446 else if (floater_name == "mute list")
6447 {
6448 LLFloaterMute::toggle(NULL);
6449 }
6450 else if (floater_name == "camera controls")
6451 {
6452 LLFloaterCamera::toggle(NULL);
6453 }
6454 else if (floater_name == "movement controls")
6455 {
6456 LLFloaterMove::show(NULL);
6457 }
6458 else if (floater_name == "world map")
6459 {
6460 LLFloaterWorldMap::toggle(NULL);
6461 }
6462 else if (floater_name == "mini map")
6463 {
6464 LLFloaterMap::toggle(NULL);
6465 }
6466 else if (floater_name == "stat bar")
6467 {
6468 gDebugView->mStatViewp->setVisible(!gDebugView->mStatViewp->getVisible());
6469 }
6470 else if (floater_name == "account history")
6471 {
6472 LLFloaterAccountHistory::show(NULL);
6473 }
6474 else if (floater_name == "my land")
6475 {
6476 LLFloaterLandHoldings::show(NULL);
6477 }
6478 else if (floater_name == "about land")
6479 {
6480 if (gParcelMgr->selectionEmpty())
6481 {
6482 if (gLastHitPosGlobal.isExactlyZero())
6483 {
6484 gParcelMgr->selectParcelAt(gAgent.getPositionGlobal());
6485 }
6486 else
6487 {
6488 gParcelMgr->selectParcelAt( gLastHitPosGlobal );
6489 }
6490 }
6491
6492 LLFloaterLand::show();
6493 }
6494 else if (floater_name == "buy land")
6495 {
6496 if (gParcelMgr->selectionEmpty())
6497 {
6498 if (gLastHitPosGlobal.isExactlyZero())
6499 {
6500 gParcelMgr->selectParcelAt(gAgent.getPositionGlobal());
6501 }
6502 else
6503 {
6504 gParcelMgr->selectParcelAt( gLastHitPosGlobal );
6505 }
6506 }
6507
6508 gParcelMgr->startBuyLand();
6509 }
6510 else if (floater_name == "about region")
6511 {
6512 LLFloaterRegionInfo::show((void *)NULL);
6513 }
6514 else if (floater_name == "grid options")
6515 {
6516 LLFloaterBuildOptions::show(NULL);
6517 }
6518 else if (floater_name == "script errors")
6519 {
6520 LLFloaterScriptDebug::show(LLUUID::null);
6521 }
6522 else if (floater_name == "help")
6523 {
6524#if LL_LIBXUL_ENABLED
6525 LLHtmlHelp::show(NULL);
6526#endif
6527 }
6528 else if (floater_name == "complaint reporter")
6529 {
6530 // Prevent menu from appearing in screen shot.
6531 gMenuHolder->hideMenus();
6532 LLFloaterReporter::showFromMenu(COMPLAINT_REPORT);
6533 }
6534 else if (floater_name == "mean events")
6535 {
6536 if (!gNoRender)
6537 {
6538 LLFloaterBump::show(NULL);
6539 }
6540 }
6541 else if (floater_name == "bug reporter")
6542 {
6543 // Prevent menu from appearing in screen shot.
6544 gMenuHolder->hideMenus();
6545 LLFloaterReporter::showFromMenu(BUG_REPORT);
6546 }
6547 else if (floater_name == "buy currency")
6548 {
6549 LLFloaterBuyCurrency::buyCurrency();
6550 }
6551 else if (floater_name == "about")
6552 {
6553 LLFloaterAbout::show(NULL);
6554 }
6555 return true;
6556 }
6557};
6558
6559class LLFloaterVisible : public view_listener_t
6560{
6561 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6562 {
6563 LLString control_name = userdata["control"].asString();
6564 LLString floater_name = userdata["data"].asString();
6565 bool new_value = false;
6566 if (floater_name == "friends")
6567 {
6568 new_value = LLFloaterFriends::visible(NULL);
6569 }
6570 else if (floater_name == "toolbar")
6571 {
6572 new_value = LLToolBar::visible(NULL);
6573 }
6574 else if (floater_name == "chat history")
6575 {
6576 new_value = LLFloaterChat::visible(NULL);
6577 }
6578 else if (floater_name == "im")
6579 {
6580 new_value = gIMView && gIMView->mTalkFloater && gIMView->mTalkFloater->getVisible();
6581 }
6582 else if (floater_name == "mute list")
6583 {
6584 new_value = LLFloaterMute::visible(NULL);
6585 }
6586 else if (floater_name == "camera controls")
6587 {
6588 new_value = LLFloaterCamera::visible(NULL);
6589 }
6590 else if (floater_name == "movement controls")
6591 {
6592 new_value = LLFloaterMove::visible(NULL);
6593 }
6594 else if (floater_name == "stat bar")
6595 {
6596 new_value = gDebugView->mStatViewp->getVisible();
6597 }
6598 gMenuHolder->findControl(control_name)->setValue(new_value);
6599 return true;
6600 }
6601};
6602
6603void callback_show_url(S32 option, void* url)
6604{
6605 const char* urlp = (const char*)url;
6606 if (0 == option)
6607 {
6608 LLWeb::loadURL(urlp);
6609 }
6610 delete urlp;
6611}
6612
6613class LLPromptShowURL : public view_listener_t
6614{
6615 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6616 {
6617 LLString param = userdata.asString();
6618 LLString::size_type offset = param.find(",");
6619 if (offset != param.npos)
6620 {
6621 LLString alert = param.substr(0, offset);
6622 LLString url = param.substr(offset+1);
6623 char *url_copy = new char[url.size()+1];
6624 strcpy(url_copy, url.c_str());
6625 gViewerWindow->alertXml(alert, callback_show_url, url_copy);
6626 }
6627 else
6628 {
6629 llinfos << "PromptShowURL invalid parameters! Expecting \"ALERT,URL\"." << llendl;
6630 }
6631 return true;
6632 }
6633};
6634
6635void callback_show_file(S32 option, void* filename)
6636{
6637 const char* filenamep = (const char*)filename;
6638 if (0 == option)
6639 {
6640 load_url_local_file(filenamep);
6641 }
6642 delete filenamep;
6643}
6644
6645class LLPromptShowFile : public view_listener_t
6646{
6647 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6648 {
6649 LLString param = userdata.asString();
6650 LLString::size_type offset = param.find(",");
6651 if (offset != param.npos)
6652 {
6653 LLString alert = param.substr(0, offset);
6654 LLString file = param.substr(offset+1);
6655 char *file_copy = new char[file.size()+1];
6656 strcpy(file_copy, file.c_str());
6657 gViewerWindow->alertXml(alert, callback_show_file, file_copy);
6658 }
6659 else
6660 {
6661 llinfos << "PromptShowFile invalid parameters! Expecting \"ALERT,FILE\"." << llendl;
6662 }
6663 return true;
6664 }
6665};
6666
6667class LLShowAgentProfile : public view_listener_t
6668{
6669 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6670 {
6671 LLUUID agent_id;
6672 if (userdata.asString() == "agent")
6673 {
6674 agent_id = gAgent.getID();
6675 }
6676 else if (userdata.asString() == "hit object")
6677 {
6678 agent_id = gLastHitObjectID;
6679 }
6680 else
6681 {
6682 agent_id = userdata.asUUID();
6683 }
6684
6685 LLVOAvatar* avatar = find_avatar_from_object(agent_id);
6686 if (avatar)
6687 {
6688 LLFloaterAvatarInfo::showFromAvatar(avatar);
6689 }
6690 return true;
6691 }
6692};
6693
6694class LLShowAgentGroups : public view_listener_t
6695{
6696 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6697 {
6698 LLUUID agent_id;
6699 if (userdata.asString() == "agent")
6700 {
6701 agent_id = gAgent.getID();
6702 }
6703 else
6704 {
6705 agent_id = userdata.asUUID();
6706 }
6707 if(agent_id.notNull())
6708 {
6709 LLFloaterGroups::show(agent_id, LLFloaterGroups::AGENT_GROUPS);
6710 }
6711 return true;
6712 }
6713};
6714
6715void handle_focus(void *)
6716{
6717 if (gDisconnected)
6718 {
6719 return;
6720 }
6721
6722 if (gAgent.getFocusOnAvatar())
6723 {
6724 // zoom in if we're looking at the avatar
6725 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
6726 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
6727 gAgent.cameraZoomIn(0.666f);
6728 }
6729 else
6730 {
6731 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
6732 }
6733
6734 gViewerWindow->moveCursorToCenter();
6735
6736 // Switch to camera toolset
6737// gCurrentToolset = gCameraToolset;
6738 gCurrentToolset->selectTool( gToolCamera );
6739}
6740
6741class LLLandEdit : public view_listener_t
6742{
6743 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6744 {
6745 if (gAgent.getFocusOnAvatar() && gSavedSettings.getBOOL("EditCameraMovement") )
6746 {
6747 // zoom in if we're looking at the avatar
6748 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
6749 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
6750
6751 gAgent.cameraOrbitOver( F_PI * 0.25f );
6752 gViewerWindow->moveCursorToCenter();
6753 }
6754 else if ( gSavedSettings.getBOOL("EditCameraMovement") )
6755 {
6756 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
6757 gViewerWindow->moveCursorToCenter();
6758 }
6759
6760
6761 gParcelMgr->selectParcelAt( gLastHitPosGlobal );
6762
6763 gFloaterTools->showMore(TRUE);
6764 gFloaterView->bringToFront( gFloaterTools );
6765
6766 // Switch to land edit toolset
6767 gCurrentToolset->selectTool( gToolParcel );
6768 return true;
6769 }
6770};
6771
6772class LLWorldEnableBuyLand : public view_listener_t
6773{
6774 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6775 {
6776 bool new_value = gParcelMgr->canAgentBuyParcel(
6777 gParcelMgr->selectionEmpty()
6778 ? gParcelMgr->getAgentParcel()
6779 : gParcelMgr->getSelectedParcel(),
6780 false);
6781 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
6782 return true;
6783 }
6784};
6785
6786BOOL enable_buy_land(void*)
6787{
6788 return gParcelMgr->canAgentBuyParcel(
6789 gParcelMgr->getSelectedParcel(), false);
6790}
6791
6792
6793void handle_move(void*)
6794{
6795 if (gAgent.getFocusOnAvatar())
6796 {
6797 // zoom in if we're looking at the avatar
6798 gAgent.setFocusOnAvatar(FALSE, ANIMATE);
6799 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
6800
6801 gAgent.cameraZoomIn(0.666f);
6802 }
6803 else
6804 {
6805 gAgent.setFocusGlobal(gLastHitPosGlobal + gLastHitObjectOffset, gLastHitObjectID);
6806 }
6807
6808 gViewerWindow->moveCursorToCenter();
6809
6810 gCurrentToolset = gBasicToolset;
6811 gCurrentToolset->selectTool( gToolGrab );
6812}
6813
6814
6815void near_attach_object(BOOL success, void *user_data)
6816{
6817 LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
6818
6819 U8 attachment_id;
6820 if (attachment)
6821 {
6822 attachment_id = gAgent.getAvatarObject()->mAttachmentPoints.reverseLookup(attachment);
6823 }
6824 else
6825 {
6826 // interpret 0 as "default location"
6827 attachment_id = 0;
6828 }
6829
6830 gSelectMgr->sendAttach(attachment_id);
6831}
6832
6833class LLObjectAttachToAvatar : public view_listener_t
6834{
6835 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6836 {
6837 LLViewerObject* selectedObject = gSelectMgr->getFirstRootObject();
6838 if (selectedObject)
6839 {
6840 confirm_replace_attachment(0, NULL);
6841 }
6842 return true;
6843 }
6844};
6845
6846// move this somewhere global
6847void handle_attach_to_avatar(void* user_data)
6848{
6849 LLViewerObject* selectedObject = gSelectMgr->getFirstRootObject();
6850 if (selectedObject)
6851 {
6852 LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
6853
6854 if (attachment && attachment->getObject(0))
6855 {
6856 gViewerWindow->alertXml("ReplaceAttachment", confirm_replace_attachment, user_data);
6857 }
6858 else
6859 {
6860 confirm_replace_attachment(0, user_data);
6861 }
6862 }
6863}
6864void confirm_replace_attachment(S32 option, void* user_data)
6865{
6866 if (option == 0/*YES*/)
6867 {
6868 gSelectMgr->convertTransient();
6869 LLViewerObject* selectedObject = gSelectMgr->getFirstRootObject();
6870 if (selectedObject)
6871 {
6872 const F32 MIN_STOP_DISTANCE = 1.f; // meters
6873 const F32 ARM_LENGTH = 0.5f; // meters
6874 const F32 SCALE_FUDGE = 1.5f;
6875
6876 F32 stop_distance = SCALE_FUDGE * selectedObject->getMaxScale() + ARM_LENGTH;
6877 if (stop_distance < MIN_STOP_DISTANCE)
6878 {
6879 stop_distance = MIN_STOP_DISTANCE;
6880 }
6881
6882 LLVector3 walkToSpot = selectedObject->getPositionAgent();
6883
6884 // make sure we stop in front of the object
6885 LLVector3 delta = walkToSpot - gAgent.getPositionAgent();
6886 delta.normVec();
6887 delta = delta * 0.5f;
6888 walkToSpot -= delta;
6889
6890 gAgent.startAutoPilotGlobal(gAgent.getPosGlobalFromAgent(walkToSpot), "Attach", NULL, near_attach_object, user_data, stop_distance);
6891 gAgent.clearFocusObject();
6892 }
6893 }
6894}
6895
6896class LLAttachmentDrop : public view_listener_t
6897{
6898 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
6899 {
6900 // Called when the user clicked on an object attached to them
6901 // and selected "Drop".
6902 LLViewerObject *object = gViewerWindow->lastObjectHit();
6903 if (!object)
6904 {
6905 llwarns << "handle_drop_attachment() - no object to drop" << llendl;
6906 return true;
6907 }
6908
6909 LLViewerObject *parent = (LLViewerObject*)object->getParent();
6910 while (parent)
6911 {
6912 if(parent->isAvatar())
6913 {
6914 break;
6915 }
6916 object = parent;
6917 parent = (LLViewerObject*)parent->getParent();
6918 }
6919
6920 if (!object)
6921 {
6922 llwarns << "handle_detach() - no object to detach" << llendl;
6923 return true;
6924 }
6925
6926 if (object->isAvatar())
6927 {
6928 llwarns << "Trying to detach avatar from avatar." << llendl;
6929 return true;
6930 }
6931
6932 // The sendDropAttachment() method works on the list of selected
6933 // objects. Thus we need to clear the list, make sure it only
6934 // contains the object the user clicked, send the message,
6935 // then clear the list.
6936 // We use deselectAll to update the simulator's notion of what's
6937 // selected, and removeAll just to change things locally.
6938 //gSelectMgr->deselectAll();
6939 //gSelectMgr->selectObjectAndFamily(object);
6940 gSelectMgr->sendDropAttachment();
6941 gSelectMgr->deselectTransient();
6942 return true;
6943 }
6944};
6945
6946// called from avatar pie menu
6947void handle_detach_from_avatar(void* user_data)
6948{
6949 LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
6950
6951 LLViewerObject* attached_object = attachment->getObject(0);
6952
6953 if (attached_object)
6954 {
6955 gMessageSystem->newMessage("ObjectDetach");
6956 gMessageSystem->nextBlockFast(_PREHASH_AgentData);
6957 gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
6958 gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
6959
6960 gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
6961 gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID());
6962 gMessageSystem->sendReliable( gAgent.getRegionHost() );
6963 }
6964}
6965
6966void attach_label(LLString& label, void* user_data)
6967{
6968 LLViewerJointAttachment* attachmentp = (LLViewerJointAttachment*)user_data;
6969 if (attachmentp)
6970 {
6971 label = attachmentp->getName();
6972 if (attachmentp->getObject(0))
6973 {
6974 LLViewerInventoryItem* itemp = gInventory.getItem(attachmentp->getItemID());
6975 if (itemp)
6976 {
6977 label += LLString(" (") + itemp->getName() + LLString(")");
6978 }
6979 }
6980 }
6981}
6982
6983void detach_label(LLString& label, void* user_data)
6984{
6985 LLViewerJointAttachment* attachmentp = (LLViewerJointAttachment*)user_data;
6986 if (attachmentp)
6987 {
6988 label = attachmentp->getName();
6989 if (attachmentp->getObject(0))
6990 {
6991 LLViewerInventoryItem* itemp = gInventory.getItem(attachmentp->getItemID());
6992 if (itemp)
6993 {
6994 label += LLString(" (") + itemp->getName() + LLString(")");
6995 }
6996 }
6997 }
6998}
6999
7000
7001class LLAttachmentDetach : public view_listener_t
7002{
7003 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7004 {
7005 // Called when the user clicked on an object attached to them
7006 // and selected "Detach".
7007 LLViewerObject *object = gViewerWindow->lastObjectHit();
7008 if (!object)
7009 {
7010 llwarns << "handle_detach() - no object to detach" << llendl;
7011 return true;
7012 }
7013
7014 LLViewerObject *parent = (LLViewerObject*)object->getParent();
7015 while (parent)
7016 {
7017 if(parent->isAvatar())
7018 {
7019 break;
7020 }
7021 object = parent;
7022 parent = (LLViewerObject*)parent->getParent();
7023 }
7024
7025 if (!object)
7026 {
7027 llwarns << "handle_detach() - no object to detach" << llendl;
7028 return true;
7029 }
7030
7031 if (object->isAvatar())
7032 {
7033 llwarns << "Trying to detach avatar from avatar." << llendl;
7034 return true;
7035 }
7036
7037 // The sendDetach() method works on the list of selected
7038 // objects. Thus we need to clear the list, make sure it only
7039 // contains the object the user clicked, send the message,
7040 // then clear the list.
7041 // We use deselectAll to update the simulator's notion of what's
7042 // selected, and removeAll just to change things locally.
7043 //RN: I thought it was more useful to detach everything that was selected
7044 if (gSelectMgr->selectionIsAttachment())
7045 {
7046 gSelectMgr->sendDetach();
7047 gSelectMgr->deselectAll();
7048 }
7049 return true;
7050 }
7051};
7052
7053//Adding an observer for a Jira 2422 and needs to be a fetch observer
7054//for Jira 3119
7055class LLWornItemFetchedObserver : public LLInventoryFetchObserver
7056{
7057public:
7058 LLWornItemFetchedObserver() {}
7059 virtual ~LLWornItemFetchedObserver() {}
7060
7061protected:
7062 virtual void done()
7063 {
7064 gPieAttachment->buildDrawLabels();
7065 gInventory.removeObserver(this);
7066 delete this;
7067 }
7068};
7069
7070// You can only drop items on parcels where you can build.
7071class LLAttachmentEnableDrop : public view_listener_t
7072{
7073 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7074 {
7075 LLParcel* parcel = gParcelMgr->getAgentParcel();
7076 BOOL can_build = gAgent.isGodlike() || (parcel && parcel->getAllowModify());
7077
7078 //Add an inventory observer to only allow dropping the newly attached item
7079 //once it exists in your inventory. Look at Jira 2422.
7080 //-jwolk
7081
7082 // A bug occurs when you wear/drop an item before it actively is added to your inventory
7083 // if this is the case (you're on a slow sim, etc.) a copy of the object,
7084 // well, a newly created object with the same properties, is placed
7085 // in your inventory. Therefore, we disable the drop option until the
7086 // item is in your inventory
7087
7088 LLViewerObject* object = gViewerWindow->lastObjectHit();
7089 LLViewerJointAttachment* attachment_pt = NULL;
7090 LLInventoryItem* item = NULL;
7091
7092 if ( object )
7093 {
7094 S32 attachmentID = ATTACHMENT_ID_FROM_STATE(object->getState());
7095 attachment_pt = gAgent.getAvatarObject()->mAttachmentPoints.getIfThere(attachmentID);
7096
7097 if ( attachment_pt )
7098 {
7099 // make sure item is in your inventory (it could be a delayed attach message being sent from the sim)
7100 // so check to see if the item is in the inventory already
7101 item = gInventory.getItem(attachment_pt->getItemID());
7102
7103 if ( !item )
7104 {
7105 // Item does not exist, make an observer to enable the pie menu
7106 // when the item finishes fetching worst case scenario
7107 // if a fetch is already out there (being sent from a slow sim)
7108 // we refetch and there are 2 fetches
7109 LLWornItemFetchedObserver* wornItemFetched = new LLWornItemFetchedObserver();
7110 LLInventoryFetchObserver::item_ref_t items; //add item to the inventory item to be fetched
7111
7112 items.push_back(attachment_pt->getItemID());
7113
7114 wornItemFetched->fetchItems(items);
7115 gInventory.addObserver(wornItemFetched);
7116 }
7117 }
7118 }
7119
7120 //now check to make sure that the item is actually in the inventory before we enable dropping it
7121 bool new_value = enable_detach(NULL) && can_build && item;
7122
7123 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7124 return true;
7125 }
7126};
7127
7128BOOL enable_detach(void*)
7129{
7130 LLViewerObject* object = gViewerWindow->lastObjectHit();
7131 if (!object) return FALSE;
7132 if (!object->isAttachment()) return FALSE;
7133
7134 // Find the avatar who owns this attachment
7135 LLViewerObject* avatar = object;
7136 while (avatar)
7137 {
7138 // ...if it's you, good to detach
7139 if (avatar->getID() == gAgent.getID())
7140 {
7141 return TRUE;
7142 }
7143
7144 avatar = (LLViewerObject*)avatar->getParent();
7145 }
7146
7147 return FALSE;
7148}
7149
7150class LLAttachmentEnableDetach : public view_listener_t
7151{
7152 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7153 {
7154 bool new_value = enable_detach(NULL);
7155 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7156 return true;
7157 }
7158};
7159
7160// Used to tell if the selected object can be attached to your avatar.
7161BOOL object_selected_and_point_valid(void *user_data)
7162{
7163 //LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
7164
7165 for (LLViewerObject *object = gSelectMgr->getFirstRootObject(); object; object = gSelectMgr->getNextRootObject())
7166 {
7167 for (U32 child_num = 0; child_num < object->mChildList.size(); child_num++ )
7168 {
7169 if (object->mChildList[child_num]->isAvatar())
7170 {
7171 return FALSE;
7172 }
7173 }
7174 }
7175
7176 return ((gSelectMgr != NULL) &&
7177 (gSelectMgr->getRootObjectCount() == 1) &&
7178 (gSelectMgr->getFirstRootObject()->getPCode() == LL_PCODE_VOLUME) &&
7179 gSelectMgr->getFirstRootObject()->permYouOwner() &&
7180 !((LLViewerObject*)gSelectMgr->getFirstRootObject()->getRoot())->isAvatar() &&
7181 (gSelectMgr->getFirstRootObject()->getNVPair("AssetContainer") == NULL));
7182}
7183
7184// Also for seeing if object can be attached. See above.
7185class LLObjectEnableWear : public view_listener_t
7186{
7187 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7188 {
7189 bool new_value = false;
7190 if (gSelectMgr)
7191 {
7192 LLViewerObject* first_root = gSelectMgr->getFirstRootObject();
7193 if (first_root)
7194 {
7195 new_value = gSelectMgr->getRootObjectCount() == 1
7196 && first_root->getPCode() == LL_PCODE_VOLUME
7197 && first_root->permYouOwner()
7198 && !((LLViewerObject*)gSelectMgr->getFirstRootObject()->getRoot())->isAvatar()
7199 && (first_root->getNVPair("AssetContainer") == NULL);
7200 }
7201 }
7202
7203 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7204 return true;
7205 }
7206};
7207
7208
7209BOOL object_attached(void *user_data)
7210{
7211 LLViewerJointAttachment *attachment = (LLViewerJointAttachment *)user_data;
7212
7213 return attachment->getObject(0) != NULL;
7214}
7215
7216class LLAvatarSendIM : public view_listener_t
7217{
7218 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7219 {
7220 LLVOAvatar* avatar = find_avatar_from_object( gViewerWindow->lastObjectHit() );
7221 if(avatar)
7222 {
7223 LLString name("IM");
7224 LLNameValue *first = avatar->getNVPair("FirstName");
7225 LLNameValue *last = avatar->getNVPair("LastName");
7226 if (first && last)
7227 {
7228 name.assign( first->getString() );
7229 name.append(" ");
7230 name.append( last->getString() );
7231 }
7232
7233 gIMView->setFloaterOpen(TRUE);
7234 //EInstantMessage type = have_agent_callingcard(gLastHitObjectID)
7235 // ? IM_SESSION_ADD : IM_SESSION_CARDLESS_START;
7236 gIMView->addSession(name,
7237 IM_NOTHING_SPECIAL,
7238 avatar->getID());
7239 }
7240 return true;
7241 }
7242};
7243
7244
7245void handle_activate(void*)
7246{
7247}
7248
7249BOOL enable_activate(void*)
7250{
7251 return FALSE;
7252}
7253
7254class LLToolsSelectedScriptAction : public view_listener_t
7255{
7256 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7257 {
7258 LLString action = userdata.asString();
7259 LLFloaterScriptQueue *queue = NULL;
7260 if (action == "compile")
7261 {
7262 queue = LLFloaterCompileQueue::create();
7263 }
7264 else if (action == "reset")
7265 {
7266 queue = LLFloaterResetQueue::create();
7267 }
7268 else if (action == "start")
7269 {
7270 queue = LLFloaterRunQueue::create();
7271 }
7272 else if (action == "stop")
7273 {
7274 queue = LLFloaterNotRunQueue::create();
7275 }
7276 if (!queue) return true;
7277
7278 BOOL scripted = FALSE;
7279 BOOL modifiable = FALSE;
7280
7281 for(LLViewerObject* obj = gSelectMgr->getFirstObject();
7282 obj;
7283 obj = gSelectMgr->getNextObject())
7284 {
7285 scripted = obj->flagScripted();
7286 modifiable = obj->permModify();
7287
7288 if( scripted && modifiable )
7289 queue->addObject(obj->getID());
7290 else
7291 break;
7292 }
7293
7294 if(!queue->start())
7295 {
7296 if ( ! scripted )
7297 {
7298 gViewerWindow->alertXml("CannotRecompileSelectObjectsNoScripts");
7299 }
7300 else if ( ! modifiable )
7301 {
7302 gViewerWindow->alertXml("CannotRecompileSelectObjectsNoPermission");
7303 }
7304 }
7305 return true;
7306 }
7307};
7308
7309void handle_reset_selection(void*)
7310{
7311 LLFloaterResetQueue* queue = LLFloaterResetQueue::create();
7312
7313 BOOL scripted = FALSE;
7314 BOOL modifiable = FALSE;
7315
7316 for(LLViewerObject* obj = gSelectMgr->getFirstObject();
7317 obj;
7318 obj = gSelectMgr->getNextObject())
7319 {
7320 scripted = obj->flagScripted();
7321 modifiable = obj->permModify();
7322
7323 if( scripted && modifiable )
7324 queue->addObject(obj->getID());
7325 else
7326 break;
7327 }
7328
7329 if(!queue->start())
7330 {
7331 if ( ! scripted )
7332 {
7333 gViewerWindow->alertXml("CannotResetSelectObjectsNoScripts");
7334 }
7335 else if ( ! modifiable )
7336 {
7337 gViewerWindow->alertXml("CannotResetSelectObjectsNoPermission");
7338 }
7339 }
7340}
7341
7342void handle_set_run_selection(void*)
7343{
7344 LLFloaterRunQueue* queue = LLFloaterRunQueue::create();
7345
7346 BOOL scripted = FALSE;
7347 BOOL modifiable = FALSE;
7348
7349 for(LLViewerObject* obj = gSelectMgr->getFirstObject();
7350 obj;
7351 obj = gSelectMgr->getNextObject())
7352 {
7353 scripted = obj->flagScripted();
7354 modifiable = obj->permModify();
7355
7356 if( scripted && modifiable )
7357 queue->addObject(obj->getID());
7358 else
7359 break;
7360 }
7361
7362 if(!queue->start())
7363 {
7364 if ( ! scripted )
7365 {
7366 gViewerWindow->alertXml("CannotSetRunningSelectObjectsNoScripts");
7367 }
7368 else if ( ! modifiable )
7369 {
7370 gViewerWindow->alertXml("CannotSerRunningSelectObjectsNoPermission");
7371 }
7372 }
7373}
7374
7375void handle_set_not_run_selection(void*)
7376{
7377 LLFloaterNotRunQueue* queue = LLFloaterNotRunQueue::create();
7378
7379 BOOL scripted = FALSE;
7380 BOOL modifiable = FALSE;
7381
7382 for(LLViewerObject* obj = gSelectMgr->getFirstObject();
7383 obj;
7384 obj = gSelectMgr->getNextObject())
7385 {
7386 scripted = obj->flagScripted();
7387 modifiable = obj->permModify();
7388
7389 if( scripted && modifiable )
7390 queue->addObject(obj->getID());
7391 else
7392 break;
7393 }
7394
7395 if(!queue->start())
7396 {
7397 if ( ! scripted )
7398 {
7399 gViewerWindow->alertXml("CannotSetRunningNotSelectObjectsNoScripts");
7400 }
7401 else if ( ! modifiable )
7402 {
7403 gViewerWindow->alertXml("CannotSerRunningNotSelectObjectsNoPermission");
7404 }
7405 }
7406}
7407
7408void handle_selected_texture_info(void*)
7409{
7410 LLSelectNode* node = NULL;
7411 for (node = gSelectMgr->getFirstNode(); node != NULL; node = gSelectMgr->getNextNode())
7412 {
7413 if (!node->mValid) continue;
7414
7415 std::string msg;
7416 msg.assign("Texture info for: ");
7417 msg.append(node->mName);
7418 LLChat chat(msg);
7419 LLFloaterChat::addChat(chat);
7420
7421 U8 te_count = node->getObject()->getNumTEs();
7422 // map from texture ID to list of faces using it
7423 typedef std::map< LLUUID, std::vector<U8> > map_t;
7424 map_t faces_per_texture;
7425 for (U8 i = 0; i < te_count; i++)
7426 {
7427 if (!node->isTESelected(i)) continue;
7428
7429 LLViewerImage* img = node->getObject()->getTEImage(i);
7430 LLUUID image_id = img->getID();
7431 faces_per_texture[image_id].push_back(i);
7432 }
7433 // Per-texture, dump which faces are using it.
7434 map_t::iterator it;
7435 for (it = faces_per_texture.begin(); it != faces_per_texture.end(); ++it)
7436 {
7437 LLUUID image_id = it->first;
7438 U8 te = it->second[0];
7439 LLViewerImage* img = node->getObject()->getTEImage(te);
7440 S32 height = img->getHeight();
7441 S32 width = img->getWidth();
7442 S32 components = img->getComponents();
7443 std::string image_id_string;
7444 if (gAgent.isGodlike())
7445 {
7446 image_id_string = image_id.getString() + " ";
7447 }
7448 msg = llformat("%s%dx%d %s on face ",
7449 image_id_string.c_str(),
7450 width,
7451 height,
7452 (components == 4 ? "alpha" : "opaque"));
7453 for (U8 i = 0; i < it->second.size(); ++i)
7454 {
7455 msg.append( llformat("%d ", (S32)(it->second[i])));
7456 }
7457 LLChat chat(msg);
7458 LLFloaterChat::addChat(chat);
7459 }
7460 }
7461}
7462
7463void handle_dump_image_list(void*)
7464{
7465 gImageList.dump();
7466}
7467
7468void handle_test_male(void*)
7469{
7470 wear_outfit_by_name("Male Shape & Outfit");
7471 //gGestureList.requestResetFromServer( TRUE );
7472}
7473
7474void handle_test_female(void*)
7475{
7476 wear_outfit_by_name("Female Shape & Outfit");
7477 //gGestureList.requestResetFromServer( FALSE );
7478}
7479
7480void handle_toggle_pg(void*)
7481{
7482 if (gAgent.mAccess < SIM_ACCESS_MATURE)
7483 {
7484 gAgent.mAccess = SIM_ACCESS_MATURE;
7485 }
7486 else
7487 {
7488 gAgent.mAccess = SIM_ACCESS_PG;
7489 }
7490
7491 LLFloaterWorldMap::reloadIcons(NULL);
7492
7493 llinfos << "Access set to " << (S32)gAgent.mAccess << llendl;
7494}
7495
7496void handle_dump_attachments(void*)
7497{
7498 LLVOAvatar* avatar = gAgent.getAvatarObject();
7499 if( !avatar )
7500 {
7501 llinfos << "NO AVATAR" << llendl;
7502 return;
7503 }
7504
7505 for( LLViewerJointAttachment* attachment = avatar->mAttachmentPoints.getFirstData();
7506 attachment;
7507 attachment = avatar->mAttachmentPoints.getNextData() )
7508 {
7509 S32 key = avatar->mAttachmentPoints.getCurrentKeyWithoutIncrement();
7510 BOOL visible = (attachment->getObject(0) != NULL &&
7511 attachment->getObject(0)->mDrawable.notNull() &&
7512 !attachment->getObject(0)->mDrawable->isRenderType(0));
7513 LLVector3 pos;
7514 if (visible) pos = attachment->getObject(0)->mDrawable->getPosition();
7515 llinfos << "ATTACHMENT " << key << ": item_id=" << attachment->getItemID()
7516 << (attachment->getObject(0) ? " present " : " absent ")
7517 << (visible ? "visible " : "invisible ")
7518 << " at " << pos
7519 << " and " << (visible ? attachment->getObject(0)->getPosition() : LLVector3::zero)
7520 << llendl;
7521 }
7522}
7523
7524//---------------------------------------------------------------------
7525// Callbacks for enabling/disabling items
7526//---------------------------------------------------------------------
7527
7528BOOL menu_ui_enabled(void *user_data)
7529{
7530 BOOL high_res = gSavedSettings.getBOOL( "HighResSnapshot" );
7531 return !high_res;
7532}
7533
7534// TomY TODO DEPRECATE & REMOVE
7535void menu_toggle_control( void* user_data )
7536{
7537 BOOL checked = gSavedSettings.getBOOL( static_cast<char*>(user_data) );
7538 if (LLString(static_cast<char*>(user_data)) == "HighResSnapshot" && !checked)
7539 {
7540 // High Res Snapshot active, must uncheck RenderUIInSnapshot
7541 gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE );
7542 }
7543 gSavedSettings.setBOOL( static_cast<char*>(user_data), !checked );
7544}
7545
7546
7547// these are used in the gl menus to set control values.
7548class LLToggleControl : public view_listener_t
7549{
7550 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7551 {
7552 LLString control_name = userdata.asString();
7553 BOOL checked = gSavedSettings.getBOOL( control_name );
7554 if (control_name == "HighResSnapshot" && !checked)
7555 {
7556 // High Res Snapshot active, must uncheck RenderUIInSnapshot
7557 gSavedSettings.setBOOL( "RenderUIInSnapshot", FALSE );
7558 }
7559 gSavedSettings.setBOOL( control_name, !checked );
7560 return true;
7561 }
7562};
7563
7564// As above, but can be a callback from a LLCheckboxCtrl
7565void check_toggle_control( LLUICtrl *, void* user_data )
7566{
7567 BOOL checked = gSavedSettings.getBOOL( static_cast<char*>(user_data) );
7568 gSavedSettings.setBOOL( static_cast<char*>(user_data), !checked );
7569}
7570
7571BOOL menu_check_control( void* user_data)
7572{
7573 return gSavedSettings.getBOOL((char*)user_data);
7574}
7575
7576//
7577void menu_toggle_variable( void* user_data )
7578{
7579 BOOL checked = *(BOOL*)user_data;
7580 *(BOOL*)user_data = !checked;
7581}
7582
7583BOOL menu_check_variable( void* user_data)
7584{
7585 return *(BOOL*)user_data;
7586}
7587
7588
7589BOOL enable_land_selected( void* )
7590{
7591 return gParcelMgr && !(gParcelMgr->selectionEmpty());
7592}
7593
7594class LLSomethingSelected : public view_listener_t
7595{
7596 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7597 {
7598 bool new_value = !(gSelectMgr->isEmpty());
7599 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7600 return true;
7601 }
7602};
7603
7604class LLSomethingSelectedNoHUD : public view_listener_t
7605{
7606 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7607 {
7608 bool new_value = !(gSelectMgr->isEmpty()) && !(gSelectMgr->getSelectType() == SELECT_TYPE_HUD);
7609 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7610 return true;
7611 }
7612};
7613
7614BOOL enable_more_than_one_selected(void* )
7615{
7616 return (gSelectMgr->getObjectCount() > 1);
7617}
7618
7619class LLEditableSelected : public view_listener_t
7620{
7621 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7622 {
7623 bool new_value = (gSelectMgr->getFirstEditableObject() != NULL);
7624 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7625 return true;
7626 }
7627};
7628
7629class LLToolsEnableTakeCopy : public view_listener_t
7630{
7631 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7632 {
7633 bool new_value = false;
7634 if (gSelectMgr)
7635 {
7636 new_value = true;
7637#ifndef HACKED_GODLIKE_VIEWER
7638# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
7639 if (gInProductionGrid || !gAgent.isGodlike())
7640# endif
7641 {
7642 LLViewerObject* obj = gSelectMgr->getFirstRootObject();
7643 if(obj)
7644 {
7645 for( ; obj; obj = gSelectMgr->getNextRootObject())
7646 {
7647 if(!(obj->permCopy()) || obj->isAttachment())
7648 {
7649 new_value = false;
7650 }
7651 }
7652 }
7653 }
7654#endif // HACKED_GODLIKE_VIEWER
7655 }
7656
7657 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7658 return true;
7659 }
7660};
7661
7662BOOL enable_selection_you_own_all(void*)
7663{
7664 LLViewerObject *obj;
7665 for (obj = gSelectMgr->getFirstRootObject(); obj; obj = gSelectMgr->getNextRootObject())
7666 {
7667 if (!obj->permYouOwner())
7668 {
7669 return FALSE;
7670 }
7671 }
7672
7673 return TRUE;
7674}
7675
7676BOOL enable_selection_you_own_one(void*)
7677{
7678 LLViewerObject *obj;
7679 for (obj = gSelectMgr->getFirstRootObject(); obj; obj = gSelectMgr->getNextRootObject())
7680 {
7681 if (obj->permYouOwner())
7682 {
7683 return TRUE;
7684 }
7685 }
7686
7687 return FALSE;
7688}
7689
7690class LLHasAsset : public LLInventoryCollectFunctor
7691{
7692public:
7693 LLHasAsset(const LLUUID& id) : mAssetID(id), mHasAsset(FALSE) {}
7694 virtual ~LLHasAsset() {}
7695 virtual bool operator()(LLInventoryCategory* cat,
7696 LLInventoryItem* item);
7697 BOOL hasAsset() const { return mHasAsset; }
7698
7699protected:
7700 LLUUID mAssetID;
7701 BOOL mHasAsset;
7702};
7703
7704bool LLHasAsset::operator()(LLInventoryCategory* cat,
7705 LLInventoryItem* item)
7706{
7707 if(item && item->getAssetUUID() == mAssetID)
7708 {
7709 mHasAsset = TRUE;
7710 }
7711 return FALSE;
7712}
7713
7714BOOL enable_save_into_inventory(void*)
7715{
7716 if(gSelectMgr)
7717 {
7718 // find the last root
7719 LLSelectNode* last_node = NULL;
7720 for(LLSelectNode* node = gSelectMgr->getFirstRootNode();
7721 node != NULL;
7722 node = gSelectMgr->getNextRootNode())
7723 {
7724 last_node = node;
7725 }
7726
7727#ifdef HACKED_GODLIKE_VIEWER
7728 return TRUE;
7729#else
7730# ifdef TOGGLE_HACKED_GODLIKE_VIEWER
7731 if (!gInProductionGrid && gAgent.isGodlike())
7732 {
7733 return TRUE;
7734 }
7735# endif
7736 // check all pre-req's for save into inventory.
7737 if(last_node && last_node->mValid && !last_node->mItemID.isNull()
7738 && (last_node->mPermissions->getOwner() == gAgent.getID())
7739 && (gInventory.getItem(last_node->mItemID) != NULL))
7740 {
7741 LLViewerObject* obj = last_node->getObject();
7742 if( obj && !obj->isAttachment() )
7743 {
7744 return TRUE;
7745 }
7746 }
7747#endif
7748 }
7749 return FALSE;
7750}
7751
7752class LLToolsEnableSaveToInventory : public view_listener_t
7753{
7754 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7755 {
7756 bool new_value = enable_save_into_inventory(NULL);
7757 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7758 return true;
7759 }
7760};
7761
7762BOOL enable_save_into_task_inventory(void*)
7763{
7764 if(gSelectMgr)
7765 {
7766 LLSelectNode* node = gSelectMgr->getFirstRootNode();
7767 if(node && (node->mValid) && (!node->mFromTaskID.isNull()))
7768 {
7769 // *TODO: check to see if the fromtaskid object exists.
7770 LLViewerObject* obj = node->getObject();
7771 if( obj && !obj->isAttachment() )
7772 {
7773 return TRUE;
7774 }
7775 }
7776 }
7777 return FALSE;
7778}
7779
7780class LLToolsEnableSaveToObjectInventory : public view_listener_t
7781{
7782 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7783 {
7784 bool new_value = enable_save_into_task_inventory(NULL);
7785 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7786 return true;
7787 }
7788};
7789
7790BOOL enable_not_thirdperson(void*)
7791{
7792 return !gAgent.cameraThirdPerson();
7793}
7794
7795class LLFileEnableUpload : public view_listener_t
7796{
7797 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7798 {
7799 bool new_value = gStatusBar && gGlobalEconomy && (gStatusBar->getBalance() >= gGlobalEconomy->getPriceUpload());
7800 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7801 return true;
7802 }
7803};
7804
7805BOOL enable_export_selected(void *)
7806{
7807 if (gSelectMgr->isEmpty())
7808 {
7809 return FALSE;
7810 }
7811 if (!gExporterRequestID.isNull())
7812 {
7813 return FALSE;
7814 }
7815 if (!LLUploadDialog::modalUploadIsFinished())
7816 {
7817 return FALSE;
7818 }
7819 return TRUE;
7820}
7821
7822class LLViewEnableMouselook : public view_listener_t
7823{
7824 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7825 {
7826 // You can't go directly from customize avatar to mouselook.
7827 // TODO: write code with appropriate dialogs to handle this transition.
7828 bool new_value = (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgent.getCameraMode() && !gSavedSettings.getBOOL("FreezeTime"));
7829 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7830 return true;
7831 }
7832};
7833
7834class LLToolsEnableToolNotPie : public view_listener_t
7835{
7836 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7837 {
7838 bool new_value = ( gToolMgr->getCurrentTool(MASK_NONE) != gToolPie );
7839 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7840 return true;
7841 }
7842};
7843
7844class LLWorldEnableCreateLandmark : public view_listener_t
7845{
7846 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7847 {
7848 bool new_value = gAgent.isGodlike() ||
7849 (gAgent.getRegion() && gAgent.getRegion()->getAllowLandmark());
7850 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7851 return true;
7852 }
7853};
7854
7855class LLWorldEnableSetHomeLocation : public view_listener_t
7856{
7857 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7858 {
7859 bool new_value = gAgent.isGodlike() ||
7860 (gAgent.getRegion() && gAgent.getRegion()->getAllowSetHome());
7861 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7862 return true;
7863 }
7864};
7865
7866BOOL enable_region_owner(void*)
7867{
7868 if(gAgent.getRegion() && gAgent.getRegion()->getOwner() == gAgent.getID())
7869 return TRUE;
7870 return enable_god_customer_service(NULL);
7871}
7872
7873BOOL enable_god_full(void*)
7874{
7875 return gAgent.getGodLevel() >= GOD_FULL;
7876}
7877
7878BOOL enable_god_liaison(void*)
7879{
7880 return gAgent.getGodLevel() >= GOD_LIAISON;
7881}
7882
7883BOOL enable_god_customer_service(void*)
7884{
7885 return gAgent.getGodLevel() >= GOD_CUSTOMER_SERVICE;
7886}
7887
7888BOOL enable_god_basic(void*)
7889{
7890 return gAgent.getGodLevel() > GOD_NOT;
7891}
7892
7893void toggle_vbo(void *)
7894{
7895 gPipeline.mUseVBO = !gPipeline.mUseVBO;
7896
7897 if (!gPipeline.usingAGP())
7898 {
7899 return;
7900 }
7901
7902 gPipeline.setUseAGP(FALSE);
7903 gPipeline.setUseAGP(TRUE);
7904
7905 gSavedSettings.setBOOL("RenderUseVBO", gPipeline.mUseVBO);
7906}
7907
7908BOOL check_vbo(void *)
7909{
7910 return gPipeline.mUseVBO;
7911}
7912
7913#if 0 // 1.9.2
7914void toggle_vertex_shaders(void *)
7915{
7916 BOOL use_shaders = gPipeline.getUseVertexShaders();
7917 gPipeline.setUseVertexShaders(use_shaders);
7918}
7919
7920BOOL check_vertex_shaders(void *)
7921{
7922 return gPipeline.getUseVertexShaders();
7923}
7924#endif
7925
7926void toggle_glow(void *)
7927{
7928 gRenderLightGlows = !gRenderLightGlows;
7929
7930 gSavedSettings.setBOOL("RenderLightGlows", gRenderLightGlows);
7931}
7932
7933BOOL check_glow(void *)
7934{
7935 return gRenderLightGlows;
7936}
7937
7938
7939void toggle_show_xui_names(void *)
7940{
7941 BOOL showXUINames = gSavedSettings.getBOOL("ShowXUINames");
7942
7943 showXUINames = !showXUINames;
7944 gSavedSettings.setBOOL("ShowXUINames", showXUINames);
7945}
7946
7947BOOL check_show_xui_names(void *)
7948{
7949 return gSavedSettings.getBOOL("ShowXUINames");
7950}
7951
7952
7953
7954void toggle_cull_small(void *)
7955{
7956// gPipeline.mCullBySize = !gPipeline.mCullBySize;
7957//
7958// gSavedSettings.setBOOL("RenderCullBySize", gPipeline.mCullBySize);
7959}
7960
7961class LLToolsSelectOnlyMyObjects : public view_listener_t
7962{
7963 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7964 {
7965 BOOL cur_val = gSavedSettings.getBOOL("SelectOwnedOnly");
7966
7967 gSavedSettings.setBOOL("SelectOwnedOnly", ! cur_val );
7968
7969 return true;
7970 }
7971};
7972
7973class LLToolsSelectOnlyMovableObjects : public view_listener_t
7974{
7975 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7976 {
7977 BOOL cur_val = gSavedSettings.getBOOL("SelectMovableOnly");
7978
7979 gSavedSettings.setBOOL("SelectMovableOnly", ! cur_val );
7980
7981 return true;
7982 }
7983};
7984
7985class LLToolsSelectBySurrounding : public view_listener_t
7986{
7987 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7988 {
7989 LLSelectMgr::sRectSelectInclusive = !LLSelectMgr::sRectSelectInclusive;
7990
7991 gSavedSettings.setBOOL("RectangleSelectInclusive", LLSelectMgr::sRectSelectInclusive);
7992 return true;
7993 }
7994};
7995
7996class LLToolsShowHiddenSelection : public view_listener_t
7997{
7998 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7999 {
8000 // TomY TODO Merge these
8001 LLSelectMgr::sRenderHiddenSelections = !LLSelectMgr::sRenderHiddenSelections;
8002
8003 gSavedSettings.setBOOL("RenderHiddenSelections", LLSelectMgr::sRenderHiddenSelections);
8004 return true;
8005 }
8006};
8007
8008class LLToolsShowSelectionLightRadius : public view_listener_t
8009{
8010 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8011 {
8012 // TomY TODO merge these
8013 LLSelectMgr::sRenderLightRadius = !LLSelectMgr::sRenderLightRadius;
8014
8015 gSavedSettings.setBOOL("RenderLightRadius", LLSelectMgr::sRenderLightRadius);
8016 return true;
8017 }
8018};
8019
8020void reload_personal_settings_overrides(void *)
8021{
8022 llinfos << "Loading overrides from " << gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,"overrides.xml") << llendl;
8023
8024 gSavedSettings.loadFromFile(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT,"overrides.xml"));
8025}
8026
8027void force_breakpoint(void *)
8028{
8029#if LL_WINDOWS // Forcing a breakpoint
8030 DebugBreak();
8031#endif
8032}
8033
8034void reload_vertex_shader(void *)
8035{
8036 //THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought - DaveP
8037}
8038
8039void flush_animations(void *)
8040{
8041 if (gAgent.getAvatarObject())
8042 {
8043 gAgent.getAvatarObject()->resetAnimations();
8044 }
8045}
8046
8047void slow_mo_animations(void*)
8048{
8049 static BOOL slow_mo = FALSE;
8050 if (slow_mo)
8051 {
8052 gAgent.getAvatarObject()->setAnimTimeFactor(1.f);
8053 slow_mo = FALSE;
8054 }
8055 else
8056 {
8057 gAgent.getAvatarObject()->setAnimTimeFactor(0.2f);
8058 slow_mo = TRUE;
8059 }
8060}
8061
8062void handle_dump_avatar_local_textures(void*)
8063{
8064 LLVOAvatar* avatar = gAgent.getAvatarObject();
8065 if( avatar )
8066 {
8067 avatar->dumpLocalTextures();
8068 }
8069}
8070
8071void handle_debug_avatar_textures(void*)
8072{
8073 LLFloaterAvatarTextures::show(gLastHitObjectID);
8074}
8075
8076void handle_grab_texture(void* data)
8077{
8078 LLVOAvatar::ETextureIndex index = (LLVOAvatar::ETextureIndex) ((U32) data);
8079 LLVOAvatar* avatar = gAgent.getAvatarObject();
8080 if ( avatar )
8081 {
8082 const LLUUID& asset_id = avatar->grabLocalTexture(index);
8083 llinfos << "Adding baked texture " << asset_id << " to inventory." << llendl;
8084 LLAssetType::EType asset_type = LLAssetType::AT_TEXTURE;
8085 LLInventoryType::EType inv_type = LLInventoryType::IT_TEXTURE;
8086 LLUUID folder_id(gInventory.findCategoryUUIDForType(asset_type));
8087 if(folder_id.notNull())
8088 {
8089 LLString name = "Baked ";
8090 switch (index)
8091 {
8092 case LLVOAvatar::TEX_EYES_BAKED:
8093 name.append("Iris");
8094 break;
8095 case LLVOAvatar::TEX_HEAD_BAKED:
8096 name.append("Head");
8097 break;
8098 case LLVOAvatar::TEX_UPPER_BAKED:
8099 name.append("Upper Body");
8100 break;
8101 case LLVOAvatar::TEX_LOWER_BAKED:
8102 name.append("Lower Body");
8103 break;
8104 case LLVOAvatar::TEX_SKIRT_BAKED:
8105 name.append("Skirt");
8106 break;
8107 default:
8108 name.append("Unknown");
8109 break;
8110 }
8111 name.append(" Texture");
8112
8113 LLUUID item_id;
8114 item_id.generate();
8115 LLPermissions perm;
8116 perm.init(gAgentID,
8117 gAgentID,
8118 LLUUID::null,
8119 LLUUID::null);
8120 U32 next_owner_perm = PERM_MOVE | PERM_TRANSFER;
8121 perm.initMasks(PERM_ALL,
8122 PERM_ALL,
8123 PERM_NONE,
8124 PERM_NONE,
8125 next_owner_perm);
8126 S32 creation_date_now = time_corrected();
8127 LLPointer<LLViewerInventoryItem> item
8128 = new LLViewerInventoryItem(item_id,
8129 folder_id,
8130 perm,
8131 asset_id,
8132 asset_type,
8133 inv_type,
8134 name,
8135 "",
8136 LLSaleInfo::DEFAULT,
8137 LLInventoryItem::II_FLAGS_NONE,
8138 creation_date_now);
8139
8140 item->updateServer(TRUE);
8141 gInventory.updateItem(item);
8142 gInventory.notifyObservers();
8143
8144 LLInventoryView* view = LLInventoryView::getActiveInventory();
8145
8146 // Show the preview panel for textures to let
8147 // user know that the image is now in inventory.
8148 if(view)
8149 {
8150 LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
8151 LLFocusMgr::FocusLostCallback callback = gFocusMgr.getFocusCallback();
8152
8153 view->getPanel()->setSelection(item_id, TAKE_FOCUS_NO);
8154 view->getPanel()->openSelected();
8155 //LLInventoryView::dumpSelectionInformation((void*)view);
8156 // restore keyboard focus
8157 gFocusMgr.setKeyboardFocus(focus_ctrl, callback);
8158 }
8159 }
8160 else
8161 {
8162 llwarns << "Can't find a folder to put it in" << llendl;
8163 }
8164 }
8165}
8166
8167BOOL enable_grab_texture(void* data)
8168{
8169 LLVOAvatar::ETextureIndex index = (LLVOAvatar::ETextureIndex) ((U32) data);
8170 LLVOAvatar* avatar = gAgent.getAvatarObject();
8171 if ( avatar )
8172 {
8173 return avatar->canGrabLocalTexture(index);
8174 }
8175 return FALSE;
8176}
8177
8178// Returns a pointer to the avatar give the UUID of the avatar OR of an attachment the avatar is wearing.
8179// Returns NULL on failure.
8180LLVOAvatar* find_avatar_from_object( LLViewerObject* object )
8181{
8182 if (object)
8183 {
8184 if( object->isAttachment() )
8185 {
8186 do
8187 {
8188 object = (LLViewerObject*) object->getParent();
8189 }
8190 while( object && !object->isAvatar() );
8191 }
8192 else
8193 if( !object->isAvatar() )
8194 {
8195 object = NULL;
8196 }
8197 }
8198
8199 return (LLVOAvatar*) object;
8200}
8201
8202
8203// Returns a pointer to the avatar give the UUID of the avatar OR of an attachment the avatar is wearing.
8204// Returns NULL on failure.
8205LLVOAvatar* find_avatar_from_object( const LLUUID& object_id )
8206{
8207 return find_avatar_from_object( gObjectList.findObject(object_id) );
8208}
8209
8210
8211void handle_disconnect_viewer(void *)
8212{
8213 char message[2048];
8214 message[0] = '\0';
8215
8216 sprintf(message, "Testing viewer disconnect");
8217
8218 do_disconnect(message);
8219}
8220
8221
8222class LLToolsUseSelectionForGrid : public view_listener_t
8223{
8224 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8225 {
8226 gSelectMgr->clearGridObjects();
8227
8228 for (LLViewerObject* objectp = gSelectMgr->getFirstRootObject();
8229 objectp;
8230 objectp = gSelectMgr->getNextRootObject())
8231 {
8232 gSelectMgr->addGridObject(objectp);
8233 }
8234 gSelectMgr->setGridMode(GRID_MODE_REF_OBJECT);
8235 if (gFloaterTools)
8236 {
8237 gFloaterTools->mComboGridMode->setCurrentByIndex((S32)GRID_MODE_REF_OBJECT);
8238 }
8239 return true;
8240 }
8241};
8242
8243void handle_test_load_url(void*)
8244{
8245 LLWeb::loadURL("");
8246 LLWeb::loadURL("hacker://www.google.com/");
8247 LLWeb::loadURL("http");
8248 LLWeb::loadURL("http://www.google.com/");
8249}
8250
8251//
8252// LLViewerMenuHolderGL
8253//
8254
8255BOOL LLViewerMenuHolderGL::hideMenus()
8256{
8257 BOOL handled = LLMenuHolderGL::hideMenus();
8258 if (handled)
8259 {
8260 gSelectMgr->deselectTransient();
8261 if (!gFloaterTools->getVisible() && !LLFloaterLand::floaterVisible())
8262 {
8263 gParcelMgr->deselectLand();
8264 }
8265 }
8266 gMenuBarView->clearHoverItem();
8267 gMenuBarView->resetMenuTrigger();
8268
8269 return handled;
8270}
8271
8272void handle_save_to_xml(void*)
8273{
8274 LLFloater* frontmost = gFloaterView->getFrontmost();
8275 if (!frontmost)
8276 {
8277 gViewerWindow->alertXml("NoFrontmostFloater");
8278 return;
8279 }
8280
8281 LLString default_name = "floater_";
8282 default_name += frontmost->getTitle();
8283 default_name += ".xml";
8284
8285 LLString::toLower(default_name);
8286 LLString::replaceChar(default_name, ' ', '_');
8287 LLString::replaceChar(default_name, '/', '_');
8288 LLString::replaceChar(default_name, ':', '_');
8289 LLString::replaceChar(default_name, '"', '_');
8290
8291 LLFilePicker& picker = LLFilePicker::instance();
8292 if (picker.getSaveFile(LLFilePicker::FFSAVE_XML, default_name.c_str()))
8293 {
8294 LLString filename = picker.getFirstFile();
8295 gUICtrlFactory->saveToXML(frontmost, filename);
8296 }
8297}
8298
8299void handle_load_from_xml(void*)
8300{
8301 LLFilePicker& picker = LLFilePicker::instance();
8302 if (picker.getOpenFile(LLFilePicker::FFLOAD_XML))
8303 {
8304 LLString filename = picker.getFirstFile();
8305 LLFloater* floater = new LLFloater("sample_floater");
8306 gUICtrlFactory->buildFloater(floater, filename);
8307 }
8308}
8309
8310void handle_rebake_textures(void*)
8311{
8312 LLVOAvatar* avatar = gAgent.getAvatarObject();
8313 if (!avatar) return;
8314
8315 // Slam pending upload count to "unstick" things
8316 bool slam_for_debug = true;
8317 avatar->forceBakeAllTextures(slam_for_debug);
8318}
8319
8320void toggle_visibility(void* user_data)
8321{
8322 LLView* viewp = (LLView*)user_data;
8323 viewp->setVisible(!viewp->getVisible());
8324}
8325
8326BOOL get_visibility(void* user_data)
8327{
8328 LLView* viewp = (LLView*)user_data;
8329 return viewp->getVisible();
8330}
8331
8332// TomY TODO: Get rid of these?
8333class LLViewShowHoverTips : public view_listener_t
8334{
8335 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8336 {
8337 LLHoverView::sShowHoverTips = !LLHoverView::sShowHoverTips;
8338 return true;
8339 }
8340};
8341
8342class LLViewCheckShowHoverTips : public view_listener_t
8343{
8344 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8345 {
8346 bool new_value = LLHoverView::sShowHoverTips;
8347 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
8348 return true;
8349 }
8350};
8351
8352// TomY TODO: Get rid of these?
8353class LLViewHighlightTransparent : public view_listener_t
8354{
8355 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8356 {
8357 LLDrawPoolAlpha::sShowDebugAlpha = !LLDrawPoolAlpha::sShowDebugAlpha;
8358 return true;
8359 }
8360};
8361
8362class LLViewCheckHighlightTransparent : public view_listener_t
8363{
8364 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8365 {
8366 bool new_value = LLDrawPoolAlpha::sShowDebugAlpha;
8367 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
8368 return true;
8369 }
8370};
8371
8372class LLViewToggleBeacon : public view_listener_t
8373{
8374 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8375 {
8376 LLString beacon = userdata.asString();
8377 if (beacon == "scripts")
8378 {
8379 LLPipeline::toggleRenderScriptedBeacons(NULL);
8380 }
8381 else if (beacon == "physical")
8382 {
8383 LLPipeline::toggleRenderPhysicalBeacons(NULL);
8384 }
8385 else if (beacon == "sounds")
8386 {
8387 LLPipeline::toggleRenderSoundBeacons(NULL);
8388 }
8389 else if (beacon == "particles")
8390 {
8391 LLPipeline::toggleRenderParticleBeacons(NULL);
8392 }
8393 return true;
8394 }
8395};
8396
8397class LLViewCheckBeaconEnabled : public view_listener_t
8398{
8399 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8400 {
8401 LLString beacon = userdata["data"].asString();
8402 bool new_value = false;
8403 if (beacon == "scripts")
8404 {
8405 new_value = LLPipeline::getRenderScriptedBeacons(NULL);
8406 }
8407 else if (beacon == "physical")
8408 {
8409 new_value = LLPipeline::getRenderPhysicalBeacons(NULL);
8410 }
8411 else if (beacon == "sounds")
8412 {
8413 new_value = LLPipeline::getRenderSoundBeacons(NULL);
8414 }
8415 else if (beacon == "particles")
8416 {
8417 new_value = LLPipeline::getRenderParticleBeacons(NULL);
8418 }
8419 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
8420 return true;
8421 }
8422};
8423
8424class LLViewToggleRenderType : public view_listener_t
8425{
8426 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8427 {
8428 LLString type = userdata.asString();
8429 if (type == "particles")
8430 {
8431 LLPipeline::toggleRenderType((void *)(S32)LLPipeline::RENDER_TYPE_PARTICLES);
8432 }
8433 return true;
8434 }
8435};
8436
8437class LLViewCheckRenderType : public view_listener_t
8438{
8439 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8440 {
8441 LLString type = userdata["data"].asString();
8442 bool new_value = false;
8443 if (type == "particles")
8444 {
8445 new_value = LLPipeline::toggleRenderTypeControlNegated((void *)(S32)LLPipeline::RENDER_TYPE_PARTICLES);
8446 }
8447 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
8448 return true;
8449 }
8450};
8451
8452// TomY TODO: Get rid of these?
8453class LLViewShowHUDAttachments : public view_listener_t
8454{
8455 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8456 {
8457 LLDrawPoolHUD::sShowHUDAttachments = !LLDrawPoolHUD::sShowHUDAttachments;
8458 return true;
8459 }
8460};
8461
8462class LLViewCheckHUDAttachments : public view_listener_t
8463{
8464 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8465 {
8466 bool new_value = LLDrawPoolHUD::sShowHUDAttachments;
8467 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
8468 return true;
8469 }
8470};
8471
8472class LLEditEnableTakeOff : public view_listener_t
8473{
8474 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8475 {
8476 LLString control_name = userdata["control"].asString();
8477 LLString clothing = userdata["data"].asString();
8478 bool new_value = false;
8479 if (clothing == "shirt")
8480 {
8481 new_value = LLAgent::selfHasWearable((void *)WT_SHIRT);
8482 }
8483 if (clothing == "pants")
8484 {
8485 new_value = LLAgent::selfHasWearable((void *)WT_PANTS);
8486 }
8487 if (clothing == "shoes")
8488 {
8489 new_value = LLAgent::selfHasWearable((void *)WT_SHOES);
8490 }
8491 if (clothing == "socks")
8492 {
8493 new_value = LLAgent::selfHasWearable((void *)WT_SOCKS);
8494 }
8495 if (clothing == "jacket")
8496 {
8497 new_value = LLAgent::selfHasWearable((void *)WT_JACKET);
8498 }
8499 if (clothing == "gloves")
8500 {
8501 new_value = LLAgent::selfHasWearable((void *)WT_GLOVES);
8502 }
8503 if (clothing == "undershirt")
8504 {
8505 new_value = LLAgent::selfHasWearable((void *)WT_UNDERSHIRT);
8506 }
8507 if (clothing == "underpants")
8508 {
8509 new_value = LLAgent::selfHasWearable((void *)WT_UNDERPANTS);
8510 }
8511 if (clothing == "skirt")
8512 {
8513 new_value = LLAgent::selfHasWearable((void *)WT_SKIRT);
8514 }
8515 gMenuHolder->findControl(control_name)->setValue(new_value);
8516 return true;
8517 }
8518};
8519
8520class LLEditTakeOff : public view_listener_t
8521{
8522 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8523 {
8524 LLString clothing = userdata.asString();
8525 if (clothing == "shirt")
8526 {
8527 LLAgent::userRemoveWearable((void*)WT_SHIRT);
8528 }
8529 else if (clothing == "pants")
8530 {
8531 LLAgent::userRemoveWearable((void*)WT_PANTS);
8532 }
8533 else if (clothing == "shoes")
8534 {
8535 LLAgent::userRemoveWearable((void*)WT_SHOES);
8536 }
8537 else if (clothing == "socks")
8538 {
8539 LLAgent::userRemoveWearable((void*)WT_SOCKS);
8540 }
8541 else if (clothing == "jacket")
8542 {
8543 LLAgent::userRemoveWearable((void*)WT_JACKET);
8544 }
8545 else if (clothing == "gloves")
8546 {
8547 LLAgent::userRemoveWearable((void*)WT_GLOVES);
8548 }
8549 else if (clothing == "undershirt")
8550 {
8551 LLAgent::userRemoveWearable((void*)WT_UNDERSHIRT);
8552 }
8553 else if (clothing == "underpants")
8554 {
8555 LLAgent::userRemoveWearable((void*)WT_UNDERPANTS);
8556 }
8557 else if (clothing == "skirt")
8558 {
8559 LLAgent::userRemoveWearable((void*)WT_SKIRT);
8560 }
8561 else if (clothing == "all")
8562 {
8563 LLAgent::userRemoveAllClothes(NULL);
8564 }
8565 return true;
8566 }
8567};
8568
8569class LLWorldChat : public view_listener_t
8570{
8571 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8572 {
8573 handle_chat(NULL);
8574 return true;
8575 }
8576};
8577
8578class LLWorldStartGesture : public view_listener_t
8579{
8580 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8581 {
8582 handle_slash_key(NULL);
8583 return true;
8584 }
8585};
8586
8587class LLToolsSelectTool : public view_listener_t
8588{
8589 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
8590 {
8591 LLString tool_name = userdata.asString();
8592 if (tool_name == "focus")
8593 {
8594 gCurrentToolset->selectToolByIndex(1);
8595 }
8596 else if (tool_name == "move")
8597 {
8598 gCurrentToolset->selectToolByIndex(2);
8599 }
8600 else if (tool_name == "edit")
8601 {
8602 gCurrentToolset->selectToolByIndex(3);
8603 }
8604 else if (tool_name == "create")
8605 {
8606 gCurrentToolset->selectToolByIndex(4);
8607 }
8608 else if (tool_name == "land")
8609 {
8610 gCurrentToolset->selectToolByIndex(5);
8611 }
8612 return true;
8613 }
8614};
8615
8616void initialize_menu_actions()
8617{
8618 // File menu
8619 (new LLFileUploadImage())->registerListener(gMenuHolder, "File.UploadImage");
8620 (new LLFileUploadSound())->registerListener(gMenuHolder, "File.UploadSound");
8621 (new LLFileUploadAnim())->registerListener(gMenuHolder, "File.UploadAnim");
8622 (new LLFileUploadBulk())->registerListener(gMenuHolder, "File.UploadBulk");
8623 (new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow");
8624 (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture");
8625 (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot");
8626 (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk");
8627 (new LLFileSaveMovie())->registerListener(gMenuHolder, "File.SaveMovie");
8628 (new LLFileSetWindowSize())->registerListener(gMenuHolder, "File.SetWindowSize");
8629 (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit");
8630
8631 (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload");
8632 (new LLFileEnableSaveAs())->registerListener(gMenuHolder, "File.EnableSaveAs");
8633
8634 // Edit menu
8635 (new LLEditUndo())->registerListener(gMenuHolder, "Edit.Undo");
8636 (new LLEditRedo())->registerListener(gMenuHolder, "Edit.Redo");
8637 (new LLEditCut())->registerListener(gMenuHolder, "Edit.Cut");
8638 (new LLEditCopy())->registerListener(gMenuHolder, "Edit.Copy");
8639 (new LLEditPaste())->registerListener(gMenuHolder, "Edit.Paste");
8640 (new LLEditDelete())->registerListener(gMenuHolder, "Edit.Delete");
8641 (new LLEditSearch())->registerListener(gMenuHolder, "Edit.Search");
8642 (new LLEditSelectAll())->registerListener(gMenuHolder, "Edit.SelectAll");
8643 (new LLEditDeselect())->registerListener(gMenuHolder, "Edit.Deselect");
8644 (new LLEditDuplicate())->registerListener(gMenuHolder, "Edit.Duplicate");
8645 (new LLEditTakeOff())->registerListener(gMenuHolder, "Edit.TakeOff");
8646
8647 (new LLEditEnableUndo())->registerListener(gMenuHolder, "Edit.EnableUndo");
8648 (new LLEditEnableRedo())->registerListener(gMenuHolder, "Edit.EnableRedo");
8649 (new LLEditEnableCut())->registerListener(gMenuHolder, "Edit.EnableCut");
8650 (new LLEditEnableCopy())->registerListener(gMenuHolder, "Edit.EnableCopy");
8651 (new LLEditEnablePaste())->registerListener(gMenuHolder, "Edit.EnablePaste");
8652 (new LLEditEnableDelete())->registerListener(gMenuHolder, "Edit.EnableDelete");
8653 (new LLEditEnableSelectAll())->registerListener(gMenuHolder, "Edit.EnableSelectAll");
8654 (new LLEditEnableDeselect())->registerListener(gMenuHolder, "Edit.EnableDeselect");
8655 (new LLEditEnableDuplicate())->registerListener(gMenuHolder, "Edit.EnableDuplicate");
8656 (new LLEditEnableTakeOff())->registerListener(gMenuHolder, "Edit.EnableTakeOff");
8657 (new LLEditEnableCustomizeAvatar())->registerListener(gMenuHolder, "Edit.EnableCustomizeAvatar");
8658
8659 // View menu
8660 (new LLViewMouselook())->registerListener(gMenuHolder, "View.Mouselook");
8661 (new LLViewBuildMode())->registerListener(gMenuHolder, "View.BuildMode");
8662 (new LLViewResetView())->registerListener(gMenuHolder, "View.ResetView");
8663 (new LLViewLookAtLastChatter())->registerListener(gMenuHolder, "View.LookAtLastChatter");
8664 (new LLViewShowHoverTips())->registerListener(gMenuHolder, "View.ShowHoverTips");
8665 (new LLViewHighlightTransparent())->registerListener(gMenuHolder, "View.HighlightTransparent");
8666 (new LLViewToggleBeacon())->registerListener(gMenuHolder, "View.ToggleBeacon");
8667 (new LLViewToggleRenderType())->registerListener(gMenuHolder, "View.ToggleRenderType");
8668 (new LLViewShowHUDAttachments())->registerListener(gMenuHolder, "View.ShowHUDAttachments");
8669 (new LLViewZoomOut())->registerListener(gMenuHolder, "View.ZoomOut");
8670 (new LLViewZoomIn())->registerListener(gMenuHolder, "View.ZoomIn");
8671 (new LLViewZoomDefault())->registerListener(gMenuHolder, "View.ZoomDefault");
8672 (new LLViewFullscreen())->registerListener(gMenuHolder, "View.Fullscreen");
8673 (new LLViewDefaultUISize())->registerListener(gMenuHolder, "View.DefaultUISize");
8674
8675 (new LLViewEnableMouselook())->registerListener(gMenuHolder, "View.EnableMouselook");
8676 (new LLViewEnableLastChatter())->registerListener(gMenuHolder, "View.EnableLastChatter");
8677
8678 (new LLViewCheckBuildMode())->registerListener(gMenuHolder, "View.CheckBuildMode");
8679 (new LLViewCheckShowHoverTips())->registerListener(gMenuHolder, "View.CheckShowHoverTips");
8680 (new LLViewCheckHighlightTransparent())->registerListener(gMenuHolder, "View.CheckHighlightTransparent");
8681 (new LLViewCheckBeaconEnabled())->registerListener(gMenuHolder, "View.CheckBeaconEnabled");
8682 (new LLViewCheckRenderType())->registerListener(gMenuHolder, "View.CheckRenderType");
8683 (new LLViewCheckHUDAttachments())->registerListener(gMenuHolder, "View.CheckHUDAttachments");
8684
8685 // World menu
8686 (new LLWorldChat())->registerListener(gMenuHolder, "World.Chat");
8687 (new LLWorldStartGesture())->registerListener(gMenuHolder, "World.StartGesture");
8688 (new LLWorldAlwaysRun())->registerListener(gMenuHolder, "World.AlwaysRun");
8689 (new LLWorldFly())->registerListener(gMenuHolder, "World.Fly");
8690 (new LLWorldCreateLandmark())->registerListener(gMenuHolder, "World.CreateLandmark");
8691 (new LLWorldSetHomeLocation())->registerListener(gMenuHolder, "World.SetHomeLocation");
8692 (new LLWorldTeleportHome())->registerListener(gMenuHolder, "World.TeleportHome");
8693 (new LLWorldSetAway())->registerListener(gMenuHolder, "World.SetAway");
8694 (new LLWorldSetBusy())->registerListener(gMenuHolder, "World.SetBusy");
8695
8696 (new LLWorldEnableCreateLandmark())->registerListener(gMenuHolder, "World.EnableCreateLandmark");
8697 (new LLWorldEnableSetHomeLocation())->registerListener(gMenuHolder, "World.EnableSetHomeLocation");
8698 (new LLWorldEnableBuyLand())->registerListener(gMenuHolder, "World.EnableBuyLand");
8699
8700 (new LLWorldCheckAlwaysRun())->registerListener(gMenuHolder, "World.CheckAlwaysRun");
8701
8702 (new LLWorldForceSun())->registerListener(gMenuHolder, "World.ForceSun");
8703
8704 // Tools menu
8705 (new LLToolsSelectTool())->registerListener(gMenuHolder, "Tools.SelectTool");
8706 (new LLToolsSelectOnlyMyObjects())->registerListener(gMenuHolder, "Tools.SelectOnlyMyObjects");
8707 (new LLToolsSelectOnlyMovableObjects())->registerListener(gMenuHolder, "Tools.SelectOnlyMovableObjects");
8708 (new LLToolsSelectBySurrounding())->registerListener(gMenuHolder, "Tools.SelectBySurrounding");
8709 (new LLToolsShowHiddenSelection())->registerListener(gMenuHolder, "Tools.ShowHiddenSelection");
8710 (new LLToolsShowSelectionLightRadius())->registerListener(gMenuHolder, "Tools.ShowSelectionLightRadius");
8711 (new LLToolsSnapObjectXY())->registerListener(gMenuHolder, "Tools.SnapObjectXY");
8712 (new LLToolsUseSelectionForGrid())->registerListener(gMenuHolder, "Tools.UseSelectionForGrid");
8713 (new LLToolsLink())->registerListener(gMenuHolder, "Tools.Link");
8714 (new LLToolsUnlink())->registerListener(gMenuHolder, "Tools.Unlink");
8715 (new LLToolsStopAllAnimations())->registerListener(gMenuHolder, "Tools.StopAllAnimations");
8716 (new LLToolsLookAtSelection())->registerListener(gMenuHolder, "Tools.LookAtSelection");
8717 (new LLToolsBuyOrTake())->registerListener(gMenuHolder, "Tools.BuyOrTake");
8718 (new LLToolsTakeCopy())->registerListener(gMenuHolder, "Tools.TakeCopy");
8719 (new LLToolsSaveToInventory())->registerListener(gMenuHolder, "Tools.SaveToInventory");
8720 (new LLToolsSaveToObjectInventory())->registerListener(gMenuHolder, "Tools.SaveToObjectInventory");
8721 (new LLToolsSelectedScriptAction())->registerListener(gMenuHolder, "Tools.SelectedScriptAction");
8722
8723 (new LLToolsEnableToolNotPie())->registerListener(gMenuHolder, "Tools.EnableToolNotPie");
8724 (new LLToolsEnableLink())->registerListener(gMenuHolder, "Tools.EnableLink");
8725 (new LLToolsEnableUnlink())->registerListener(gMenuHolder, "Tools.EnableUnlink");
8726 (new LLToolsEnableBuyOrTake())->registerListener(gMenuHolder, "Tools.EnableBuyOrTake");
8727 (new LLToolsEnableTakeCopy())->registerListener(gMenuHolder, "Tools.EnableTakeCopy");
8728 (new LLToolsEnableSaveToInventory())->registerListener(gMenuHolder, "Tools.SaveToInventory");
8729 (new LLToolsEnableSaveToObjectInventory())->registerListener(gMenuHolder, "Tools.SaveToObjectInventory");
8730
8731 /*(new LLToolsVisibleBuyObject())->registerListener(gMenuHolder, "Tools.VisibleBuyObject");
8732 (new LLToolsVisibleTakeObject())->registerListener(gMenuHolder, "Tools.VisibleTakeObject");*/
8733
8734 // Help menu
8735 (new LLHelpLiveHelp())->registerListener(gMenuHolder, "Help.LiveHelp");
8736 (new LLHelpMOTD())->registerListener(gMenuHolder, "Help.MOTD");
8737
8738 // Self pie menu
8739 (new LLSelfStandUp())->registerListener(gMenuHolder, "Self.StandUp");
8740 (new LLSelfRemoveAllAttachments())->registerListener(gMenuHolder, "Self.RemoveAllAttachments");
8741
8742 (new LLSelfEnableStandUp())->registerListener(gMenuHolder, "Self.EnableStandUp");
8743 (new LLSelfEnableRemoveAllAttachments())->registerListener(gMenuHolder, "Self.EnableRemoveAllAttachments");
8744
8745 // Avatar pie menu
8746 (new LLObjectMute())->registerListener(gMenuHolder, "Avatar.Mute");
8747 (new LLAvatarRate())->registerListener(gMenuHolder, "Avatar.Rate");
8748 (new LLAvatarAddFriend())->registerListener(gMenuHolder, "Avatar.AddFriend");
8749 (new LLAvatarFreeze())->registerListener(gMenuHolder, "Avatar.Freeze");
8750 (new LLAvatarDebug())->registerListener(gMenuHolder, "Avatar.Debug");
8751 (new LLAvatarVisibleDebug())->registerListener(gMenuHolder, "Avatar.VisibleDebug");
8752 (new LLAvatarEnableDebug())->registerListener(gMenuHolder, "Avatar.EnableDebug");
8753 (new LLAvatarGiveCard())->registerListener(gMenuHolder, "Avatar.GiveCard");
8754 (new LLAvatarEject())->registerListener(gMenuHolder, "Avatar.Eject");
8755 (new LLAvatarSendIM())->registerListener(gMenuHolder, "Avatar.SendIM");
8756
8757 (new LLObjectEnableMute())->registerListener(gMenuHolder, "Avatar.EnableMute");
8758 (new LLAvatarEnableAddFriend())->registerListener(gMenuHolder, "Avatar.EnableAddFriend");
8759 (new LLAvatarEnableFreezeEject())->registerListener(gMenuHolder, "Avatar.EnableFreezeEject");
8760
8761 // Object pie menu
8762 (new LLObjectOpen())->registerListener(gMenuHolder, "Object.Open");
8763 (new LLObjectBuild())->registerListener(gMenuHolder, "Object.Build");
8764 (new LLObjectTouch())->registerListener(gMenuHolder, "Object.Touch");
8765 (new LLObjectSitOrStand())->registerListener(gMenuHolder, "Object.SitOrStand");
8766 (new LLObjectDelete())->registerListener(gMenuHolder, "Object.Delete");
8767 (new LLObjectAttachToAvatar())->registerListener(gMenuHolder, "Object.AttachToAvatar");
8768 (new LLObjectReturn())->registerListener(gMenuHolder, "Object.Return");
8769 (new LLObjectRateOwner())->registerListener(gMenuHolder, "Object.RateOwner");
8770 (new LLObjectReportAbuse())->registerListener(gMenuHolder, "Object.ReportAbuse");
8771 (new LLObjectRateCreator())->registerListener(gMenuHolder, "Object.RateCreator");
8772 (new LLObjectMute())->registerListener(gMenuHolder, "Object.Mute");
8773 (new LLObjectBuy())->registerListener(gMenuHolder, "Object.Buy");
8774 (new LLObjectEdit())->registerListener(gMenuHolder, "Object.Edit");
8775 (new LLObjectInspect())->registerListener(gMenuHolder, "Object.Inspect");
8776
8777 (new LLObjectEnableOpen())->registerListener(gMenuHolder, "Object.EnableOpen");
8778 (new LLObjectEnableTouch())->registerListener(gMenuHolder, "Object.EnableTouch");
8779 (new LLObjectEnableSitOrStand())->registerListener(gMenuHolder, "Object.EnableSitOrStand");
8780 (new LLObjectEnableDelete())->registerListener(gMenuHolder, "Object.EnableDelete");
8781 (new LLObjectEnableWear())->registerListener(gMenuHolder, "Object.EnableWear");
8782 (new LLObjectEnableReturn())->registerListener(gMenuHolder, "Object.EnableReturn");
8783 (new LLObjectEnableRateOwner())->registerListener(gMenuHolder, "Object.EnableRateOwner");
8784 (new LLObjectEnableReportAbuse())->registerListener(gMenuHolder, "Object.EnableReportAbuse");
8785 (new LLObjectEnableRateCreator())->registerListener(gMenuHolder, "Object.EnableRateCreator");
8786 (new LLObjectEnableMute())->registerListener(gMenuHolder, "Object.EnableMute");
8787 (new LLObjectEnableBuy())->registerListener(gMenuHolder, "Object.EnableBuy");
8788
8789 /*(new LLObjectVisibleTouch())->registerListener(gMenuHolder, "Object.VisibleTouch");
8790 (new LLObjectVisibleCustomTouch())->registerListener(gMenuHolder, "Object.VisibleCustomTouch");
8791 (new LLObjectVisibleStandUp())->registerListener(gMenuHolder, "Object.VisibleStandUp");
8792 (new LLObjectVisibleSitHere())->registerListener(gMenuHolder, "Object.VisibleSitHere");
8793 (new LLObjectVisibleCustomSit())->registerListener(gMenuHolder, "Object.VisibleCustomSit");*/
8794
8795 // Attachment pie menu
8796 (new LLAttachmentDrop())->registerListener(gMenuHolder, "Attachment.Drop");
8797 (new LLAttachmentDetach())->registerListener(gMenuHolder, "Attachment.Detach");
8798
8799 (new LLAttachmentEnableDrop())->registerListener(gMenuHolder, "Attachment.EnableDrop");
8800 (new LLAttachmentEnableDetach())->registerListener(gMenuHolder, "Attachment.EnableDetach");
8801
8802 // Land pie menu
8803 (new LLLandBuild())->registerListener(gMenuHolder, "Land.Build");
8804 (new LLLandSit())->registerListener(gMenuHolder, "Land.Sit");
8805 (new LLLandBuyPass())->registerListener(gMenuHolder, "Land.BuyPass");
8806 (new LLLandEdit())->registerListener(gMenuHolder, "Land.Edit");
8807
8808 (new LLLandEnableBuyPass())->registerListener(gMenuHolder, "Land.EnableBuyPass");
8809
8810 // Generic actions
8811 (new LLShowFloater())->registerListener(gMenuHolder, "ShowFloater");
8812 (new LLPromptShowURL())->registerListener(gMenuHolder, "PromptShowURL");
8813 (new LLPromptShowFile())->registerListener(gMenuHolder, "PromptShowFile");
8814 (new LLShowAgentProfile())->registerListener(gMenuHolder, "ShowAgentProfile");
8815 (new LLShowAgentGroups())->registerListener(gMenuHolder, "ShowAgentGroups");
8816 (new LLToggleControl())->registerListener(gMenuHolder, "ToggleControl");
8817
8818 (new LLGoToObject())->registerListener(gMenuHolder, "GoToObject");
8819 (new LLPayObject())->registerListener(gMenuHolder, "PayObject");
8820
8821 (new LLEnablePayObject())->registerListener(gMenuHolder, "EnablePayObject");
8822 (new LLEnableEdit())->registerListener(gMenuHolder, "EnableEdit");
8823
8824 (new LLFloaterVisible())->registerListener(gMenuHolder, "FloaterVisible");
8825 (new LLSomethingSelected())->registerListener(gMenuHolder, "SomethingSelected");
8826 (new LLSomethingSelectedNoHUD())->registerListener(gMenuHolder, "SomethingSelectedNoHUD");
8827 (new LLEditableSelected())->registerListener(gMenuHolder, "EditableSelected");
8828}