aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llviewermenu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llviewermenu.cpp')
-rw-r--r--linden/indra/newview/llviewermenu.cpp993
1 files changed, 27 insertions, 966 deletions
diff --git a/linden/indra/newview/llviewermenu.cpp b/linden/indra/newview/llviewermenu.cpp
index 64f1af8..1ff995e 100644
--- a/linden/indra/newview/llviewermenu.cpp
+++ b/linden/indra/newview/llviewermenu.cpp
@@ -34,15 +34,12 @@
34#include <iostream> 34#include <iostream>
35#include <fstream> 35#include <fstream>
36#include <sstream> 36#include <sstream>
37#include <boost/tokenizer.hpp>
38 37
39// linden library includes 38// linden library includes
40#include "audioengine.h" 39#include "audioengine.h"
41#include "indra_constants.h" 40#include "indra_constants.h"
42#include "llassetuploadresponders.h"
43#include "llassetstorage.h" 41#include "llassetstorage.h"
44#include "llchat.h" 42#include "llchat.h"
45#include "lleconomy.h"
46#include "llfocusmgr.h" 43#include "llfocusmgr.h"
47#include "llfontgl.h" 44#include "llfontgl.h"
48#include "llinstantmessage.h" 45#include "llinstantmessage.h"
@@ -57,7 +54,6 @@
57#include "raytrace.h" 54#include "raytrace.h"
58#include "llsdserialize.h" 55#include "llsdserialize.h"
59#include "lltimer.h" 56#include "lltimer.h"
60#include "vorbisencode.h"
61#include "llvfile.h" 57#include "llvfile.h"
62#include "llvolumemgr.h" 58#include "llvolumemgr.h"
63#include "llwindow.h" // for shell_open() 59#include "llwindow.h" // for shell_open()
@@ -83,7 +79,6 @@
83#include "llfloater.h" 79#include "llfloater.h"
84#include "llfloaterabout.h" 80#include "llfloaterabout.h"
85#include "llfloaterbuycurrency.h" 81#include "llfloaterbuycurrency.h"
86#include "llfloateranimpreview.h"
87#include "llfloateravatarinfo.h" 82#include "llfloateravatarinfo.h"
88#include "llfloateravatartextures.h" 83#include "llfloateravatartextures.h"
89#include "llfloaterbuildoptions.h" 84#include "llfloaterbuildoptions.h"
@@ -104,21 +99,17 @@
104#include "llfloaterhtml.h" 99#include "llfloaterhtml.h"
105#include "llfloaterhtmlhelp.h" 100#include "llfloaterhtmlhelp.h"
106#include "llfloaterhtmlfind.h" 101#include "llfloaterhtmlfind.h"
107#include "llfloaterimport.h"
108#include "llfloaterinspect.h" 102#include "llfloaterinspect.h"
109#include "llfloaterland.h" 103#include "llfloaterland.h"
110#include "llfloaterlandholdings.h" 104#include "llfloaterlandholdings.h"
111#include "llfloatermap.h" 105#include "llfloatermap.h"
112#include "llfloaterimagepreview.h"
113#include "llfloatermute.h" 106#include "llfloatermute.h"
114#include "llfloaternamedesc.h"
115#include "llfloateropenobject.h" 107#include "llfloateropenobject.h"
116#include "llfloaterpermissionsmgr.h" 108#include "llfloaterpermissionsmgr.h"
117#include "llfloaterpreference.h" 109#include "llfloaterpreference.h"
118#include "llfloaterregioninfo.h" 110#include "llfloaterregioninfo.h"
119#include "llfloaterreporter.h" 111#include "llfloaterreporter.h"
120#include "llfloaterscriptdebug.h" 112#include "llfloaterscriptdebug.h"
121#include "llfloatersnapshot.h"
122#include "llfloatertest.h" 113#include "llfloatertest.h"
123#include "llfloatertools.h" 114#include "llfloatertools.h"
124#include "llfloaterworldmap.h" 115#include "llfloaterworldmap.h"
@@ -147,8 +138,6 @@
147#include "llnotify.h" 138#include "llnotify.h"
148#include "llpanelobject.h" 139#include "llpanelobject.h"
149#include "llparcel.h" 140#include "llparcel.h"
150#include "llpreviewscript.h"
151#include "llpreviewtexture.h"
152#include "llprimitive.h" 141#include "llprimitive.h"
153#include "llresmgr.h" 142#include "llresmgr.h"
154#include "llselectmgr.h" 143#include "llselectmgr.h"
@@ -176,8 +165,8 @@
176#include "llviewercamera.h" 165#include "llviewercamera.h"
177#include "llviewergenericmessage.h" 166#include "llviewergenericmessage.h"
178#include "llviewergesture.h" 167#include "llviewergesture.h"
179#include "llviewerimagelist.h"
180#include "llviewerinventory.h" 168#include "llviewerinventory.h"
169#include "llviewermenufile.h" // init_menu_file()
181#include "llviewermessage.h" 170#include "llviewermessage.h"
182#include "llviewernetwork.h" 171#include "llviewernetwork.h"
183#include "llviewerobjectlist.h" 172#include "llviewerobjectlist.h"
@@ -402,7 +391,6 @@ void handle_god_request_avatar_geometry(void *); // Hack for easy testing of new
402void reload_personal_settings_overrides(void *); 391void reload_personal_settings_overrides(void *);
403void force_breakpoint(void *); 392void force_breakpoint(void *);
404void reload_vertex_shader(void *); 393void reload_vertex_shader(void *);
405void flush_animations(void *);
406void slow_mo_animations(void *); 394void slow_mo_animations(void *);
407void handle_disconnect_viewer(void *); 395void handle_disconnect_viewer(void *);
408 396
@@ -467,6 +455,7 @@ void handle_dump_avatar_local_textures(void*);
467void handle_debug_avatar_textures(void*); 455void handle_debug_avatar_textures(void*);
468void handle_grab_texture(void*); 456void handle_grab_texture(void*);
469BOOL enable_grab_texture(void*); 457BOOL enable_grab_texture(void*);
458void handle_dump_region_object_cache(void*);
470 459
471BOOL menu_ui_enabled(void *user_data); 460BOOL menu_ui_enabled(void *user_data);
472void check_toggle_control( LLUICtrl *, void* user_data ); 461void check_toggle_control( LLUICtrl *, void* user_data );
@@ -537,7 +526,7 @@ void pre_init_menus()
537 LLMenuItemGL::setHighlightFGColor( color ); 526 LLMenuItemGL::setHighlightFGColor( color );
538} 527}
539 528
540void initialize_menu_actions(); 529void initialize_menus();
541 530
542//----------------------------------------------------------------------------- 531//-----------------------------------------------------------------------------
543// Initialize main menus 532// Initialize main menus
@@ -565,7 +554,7 @@ void init_menus()
565 LLMenuGL::sMenuContainer = gMenuHolder; 554 LLMenuGL::sMenuContainer = gMenuHolder;
566 555
567 // Initialize actions 556 // Initialize actions
568 initialize_menu_actions(); 557 initialize_menus();
569 558
570 /// 559 ///
571 /// Popup menu 560 /// Popup menu
@@ -965,6 +954,8 @@ void init_debug_world_menu(LLMenuGL* menu)
965 NULL, 954 NULL,
966 &menu_check_control, 955 &menu_check_control,
967 (void*)"FixedWeather")); 956 (void*)"FixedWeather"));
957 menu->append(new LLMenuItemCallGL("Dump Region Object Cache",
958 &handle_dump_region_object_cache, NULL, NULL));
968 menu->createJumpKeys(); 959 menu->createJumpKeys();
969} 960}
970 961
@@ -1293,7 +1284,6 @@ void init_debug_avatar_menu(LLMenuGL* menu)
1293 menu->append(new LLMenuItemCallGL("Force Params to Default", &LLAgent::clearVisualParams, NULL)); 1284 menu->append(new LLMenuItemCallGL("Force Params to Default", &LLAgent::clearVisualParams, NULL));
1294 menu->append(new LLMenuItemCallGL("Reload Vertex Shader", &reload_vertex_shader, NULL)); 1285 menu->append(new LLMenuItemCallGL("Reload Vertex Shader", &reload_vertex_shader, NULL));
1295 menu->append(new LLMenuItemToggleGL("Animation Info", &LLVOAvatar::sShowAnimationDebug)); 1286 menu->append(new LLMenuItemToggleGL("Animation Info", &LLVOAvatar::sShowAnimationDebug));
1296 menu->append(new LLMenuItemCallGL("Flush Animations", &flush_animations, NULL));
1297 menu->append(new LLMenuItemCallGL("Slow Motion Animations", &slow_mo_animations, NULL)); 1287 menu->append(new LLMenuItemCallGL("Slow Motion Animations", &slow_mo_animations, NULL));
1298 menu->append(new LLMenuItemToggleGL("Show Look At", &LLHUDEffectLookAt::sDebugLookAt)); 1288 menu->append(new LLMenuItemToggleGL("Show Look At", &LLHUDEffectLookAt::sDebugLookAt));
1299 menu->append(new LLMenuItemToggleGL("Show Point At", &LLHUDEffectPointAt::sDebugPointAt)); 1289 menu->append(new LLMenuItemToggleGL("Show Point At", &LLHUDEffectPointAt::sDebugPointAt));
@@ -2041,13 +2031,13 @@ class LLAvatarDebug : public view_listener_t
2041 if( avatar ) 2031 if( avatar )
2042 { 2032 {
2043 avatar->dumpLocalTextures(); 2033 avatar->dumpLocalTextures();
2034 llinfos << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << llendl;
2035 std::vector<std::string> strings;
2036 strings.push_back(avatar->getID().asString());
2037 LLUUID invoice;
2038 send_generic_message("dumptempassetdata", strings, invoice);
2039 LLFloaterAvatarTextures::show( avatar->getID() );
2044 } 2040 }
2045 llinfos << "Dumping temporary asset data to simulator logs for avatar " << avatar->getID() << llendl;
2046 std::vector<std::string> strings;
2047 strings.push_back(avatar->getID().asString());
2048 LLUUID invoice;
2049 send_generic_message("dumptempassetdata", strings, invoice);
2050 LLFloaterAvatarTextures::show( avatar->getID() );
2051 return true; 2041 return true;
2052 } 2042 }
2053}; 2043};
@@ -2337,16 +2327,6 @@ void handle_buy_contents(LLSaleInfo sale_info)
2337 LLFloaterBuyContents::show(sale_info); 2327 LLFloaterBuyContents::show(sale_info);
2338} 2328}
2339 2329
2340class LLFileEnableSaveAs : public view_listener_t
2341{
2342 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
2343 {
2344 bool new_value = gFloaterView->getFrontmost() && gFloaterView->getFrontmost()->canSaveAs();
2345 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
2346 return true;
2347 }
2348};
2349
2350void handle_region_dump_temp_asset_data(void*) 2330void handle_region_dump_temp_asset_data(void*)
2351{ 2331{
2352 llinfos << "Dumping temporary asset data to simulator logs" << llendl; 2332 llinfos << "Dumping temporary asset data to simulator logs" << llendl;
@@ -2397,6 +2377,15 @@ void handle_dump_capabilities_info(void *)
2397 } 2377 }
2398} 2378}
2399 2379
2380void handle_dump_region_object_cache(void*)
2381{
2382 LLViewerRegion* regionp = gAgent.getRegion();
2383 if (regionp)
2384 {
2385 regionp->dumpCache();
2386 }
2387}
2388
2400void handle_dump_focus(void *) 2389void handle_dump_focus(void *)
2401{ 2390{
2402 LLView *view = gFocusMgr.getKeyboardFocus(); 2391 LLView *view = gFocusMgr.getKeyboardFocus();
@@ -4279,7 +4268,10 @@ void show_buy_currency(const char* extra)
4279 mesg << "Go to " << BUY_CURRENCY_URL << "\nfor information on purchasing currency?"; 4268 mesg << "Go to " << BUY_CURRENCY_URL << "\nfor information on purchasing currency?";
4280 4269
4281 LLString::format_map_t args; 4270 LLString::format_map_t args;
4282 args["[EXTRA]"] = extra; 4271 if (extra != NULL)
4272 {
4273 args["[EXTRA]"] = extra;
4274 }
4283 args["[URL]"] = BUY_CURRENCY_URL; 4275 args["[URL]"] = BUY_CURRENCY_URL;
4284 gViewerWindow->alertXml("PromptGoToCurrencyPage", args, 4276 gViewerWindow->alertXml("PromptGoToCurrencyPage", args,
4285 callback_show_buy_currency); 4277 callback_show_buy_currency);
@@ -4876,906 +4868,6 @@ void toggle_map( void* user_data )
4876 } 4868 }
4877} 4869}
4878 4870
4879/**
4880 char* upload_pick(void* data)
4881
4882 If applicable, brings up a file chooser in which the user selects a file
4883 to upload for a particular task. If the file is valid for the given action,
4884 returns the string to the full path filename, else returns NULL.
4885 Data is the load filter for the type of file as defined in LLFilePicker.
4886**/
4887const char* upload_pick(void* data)
4888{
4889 if( gAgent.cameraMouselook() )
4890 {
4891 gAgent.changeCameraToDefault();
4892 // This doesn't seem necessary. JC
4893 // display();
4894 }
4895
4896 LLFilePicker::ELoadFilter type;
4897 if(data)
4898 {
4899 type = (LLFilePicker::ELoadFilter)((intptr_t)data);
4900 }
4901 else
4902 {
4903 type = LLFilePicker::FFLOAD_ALL;
4904 }
4905
4906 LLFilePicker& picker = LLFilePicker::instance();
4907 if (!picker.getOpenFile(type))
4908 {
4909 llinfos << "Couldn't import objects from file" << llendl;
4910 return NULL;
4911 }
4912
4913 const char* filename = picker.getFirstFile();
4914 const char* ext = strrchr(filename, '.');
4915
4916 //strincmp doesn't like NULL pointers
4917 if (ext == NULL)
4918 {
4919 const char* short_name = strrchr(filename,
4920 *gDirUtilp->getDirDelimiter().c_str());
4921
4922 // No extension
4923 LLStringBase<char>::format_map_t args;
4924 args["[FILE]"] = LLString(short_name + 1);
4925 gViewerWindow->alertXml("NoFileExtension", args);
4926 return NULL;
4927 }
4928 else
4929 {
4930 //so there is an extension
4931 //loop over the valid extensions and compare to see
4932 //if the extension is valid
4933
4934 //now grab the set of valid file extensions
4935 const char* valids = build_extensions_string(type);
4936 std::string valid_extensions = std::string(valids);
4937
4938 BOOL ext_valid = FALSE;
4939
4940 typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
4941 boost::char_separator<char> sep(" ");
4942 tokenizer tokens(valid_extensions, sep);
4943 tokenizer::iterator token_iter;
4944
4945 //now loop over all valid file extensions
4946 //and compare them to the extension of the file
4947 //to be uploaded
4948 for( token_iter = tokens.begin();
4949 token_iter != tokens.end() && ext_valid != TRUE;
4950 ++token_iter)
4951 {
4952 const char* cur_token = token_iter->c_str();
4953
4954 if (0 == strnicmp(cur_token, ext, strlen(cur_token)) || /* Flawfinder: ignore */
4955 0 == strnicmp(cur_token, "*.*", strlen(cur_token))) /* Flawfinder: ignore */
4956 {
4957 //valid extension
4958 //or the acceptable extension is any
4959 ext_valid = TRUE;
4960 }
4961 }//end for (loop over all tokens)
4962
4963 if (ext_valid == FALSE)
4964 {
4965 //should only get here if the extension exists
4966 //but is invalid
4967 LLStringBase<char>::format_map_t args;
4968 args["[EXTENSION]"] = ext;
4969 args["[VALIDS]"] = valids;
4970 gViewerWindow->alertXml("InvalidFileExtension", args);
4971 return NULL;
4972 }
4973 }//end else (non-null extension)
4974
4975 //valid file extension
4976
4977 //now we check to see
4978 //if the file is actually a valid image/sound/etc.
4979 if (type == LLFilePicker::FFLOAD_WAV)
4980 {
4981 // pre-qualify wavs to make sure the format is acceptable
4982 char error_msg[MAX_STRING]; /* Flawfinder: ignore */
4983 if (check_for_invalid_wav_formats(filename,error_msg))
4984 {
4985 llinfos << error_msg << ": " << filename << llendl;
4986 LLStringBase<char>::format_map_t args;
4987 args["[FILE]"] = filename;
4988 gViewerWindow->alertXml( error_msg, args );
4989 return NULL;
4990 }
4991 }//end if a wave/sound file
4992
4993
4994 return filename;
4995}
4996
4997void handle_upload_object(void* data)
4998{
4999 const char* filename = upload_pick(data);
5000 if (filename)
5001 {
5002 // start the import
5003 LLFloaterImport* floaterp = new LLFloaterImport(filename);
5004 gUICtrlFactory->buildFloater(floaterp, "floater_import.xml");
5005 }
5006}
5007
5008class LLFileUploadImage : public view_listener_t
5009{
5010 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5011 {
5012 const char* filename = upload_pick((void *)(S32)LLFilePicker::FFLOAD_IMAGE);
5013 if (filename)
5014 {
5015 LLFloaterImagePreview* floaterp = new LLFloaterImagePreview(filename);
5016 gUICtrlFactory->buildFloater(floaterp, "floater_image_preview.xml");
5017 }
5018 return TRUE;
5019 }
5020};
5021
5022class LLFileUploadSound : public view_listener_t
5023{
5024 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5025 {
5026 const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_WAV));
5027 if (filename)
5028 {
5029 LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
5030 gUICtrlFactory->buildFloater(floaterp, "floater_sound_preview.xml");
5031 }
5032 return true;
5033 }
5034};
5035
5036class LLFileUploadAnim : public view_listener_t
5037{
5038 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5039 {
5040 const char* filename = upload_pick((void*)((S32)LLFilePicker::FFLOAD_ANIM));
5041 if (filename)
5042 {
5043 LLFloaterAnimPreview* floaterp = new LLFloaterAnimPreview(filename);
5044 gUICtrlFactory->buildFloater(floaterp, "floater_animation_preview.xml");
5045 }
5046 return true;
5047 }
5048};
5049
5050class LLFileUploadBulk : public view_listener_t
5051{
5052 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5053 {
5054 if( gAgent.cameraMouselook() )
5055 {
5056 gAgent.changeCameraToDefault();
5057 }
5058
5059 // TODO:
5060 // Iterate over all files
5061 // Check extensions for uploadability, cost
5062 // Check user balance for entire cost
5063 // Charge user entire cost
5064 // Loop, uploading
5065 // If an upload fails, refund the user for that one
5066 //
5067 // Also fix single upload to charge first, then refund
5068
5069 LLFilePicker& picker = LLFilePicker::instance();
5070 if (picker.getMultipleOpenFiles())
5071 {
5072 const char* filename = picker.getFirstFile();
5073 const char* name = picker.getDirname();
5074
5075 LLString asset_name = name;
5076 LLString::replaceNonstandardASCII( asset_name, '?' );
5077 LLString::replaceChar(asset_name, '|', '?');
5078 LLString::stripNonprintable(asset_name);
5079 LLString::trim(asset_name);
5080
5081 char* asset_name_str = (char*)asset_name.c_str();
5082 char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists
5083 if( !end_p )
5084 {
5085 end_p = asset_name_str + strlen( asset_name_str ); /* Flawfinder: ignore */
5086 }
5087
5088 S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
5089
5090 asset_name = asset_name.substr( 0, len );
5091
5092 upload_new_resource(filename, asset_name, asset_name, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); // file
5093 }
5094 else
5095 {
5096 llinfos << "Couldn't import objects from file" << llendl;
5097 }
5098 return true;
5099 }
5100};
5101
5102void upload_error(const char* error_message, const char* label, const std::string filename, const LLStringBase<char>::format_map_t args)
5103{
5104 llwarns << error_message << llendl;
5105 gViewerWindow->alertXml(label, args);
5106 if(remove(filename.c_str()) == -1)
5107 {
5108 lldebugs << "unable to remove temp file" << llendl;
5109 }
5110 LLFilePicker::instance().reset();
5111}
5112
5113class LLFileEnableCloseWindow : public view_listener_t
5114{
5115 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5116 {
5117 bool new_value = gFloaterView->getFocusedFloater() != NULL || gSnapshotFloaterView->getFocusedFloater() != NULL;
5118 // horrendously opaque, this code
5119 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
5120 return true;
5121 }
5122};
5123
5124class LLFileCloseWindow : public view_listener_t
5125{
5126 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5127 {
5128 LLFloater::closeFocusedFloater();
5129
5130 return true;
5131 }
5132};
5133
5134class LLFileSaveTexture : public view_listener_t
5135{
5136 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5137 {
5138 LLFloater* top = gFloaterView->getFrontmost();
5139 if (top)
5140 {
5141 top->saveAs();
5142 }
5143 return true;
5144 }
5145};
5146
5147class LLFileTakeSnapshot : public view_listener_t
5148{
5149 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5150 {
5151 LLFloaterSnapshot::show(NULL);
5152 return true;
5153 }
5154};
5155
5156class LLFileTakeSnapshotToDisk : public view_listener_t
5157{
5158 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5159 {
5160 LLPointer<LLImageRaw> raw = new LLImageRaw;
5161
5162 S32 width = gViewerWindow->getWindowDisplayWidth();
5163 S32 height = gViewerWindow->getWindowDisplayHeight();
5164
5165 if (gSavedSettings.getBOOL("HighResSnapshot"))
5166 {
5167 width *= 2;
5168 height *= 2;
5169 }
5170
5171 if (gViewerWindow->rawSnapshot(raw,
5172 width,
5173 height,
5174 TRUE,
5175 gSavedSettings.getBOOL("RenderUIInSnapshot"),
5176 FALSE))
5177 {
5178 if (!gQuietSnapshot)
5179 {
5180 gViewerWindow->playSnapshotAnimAndSound();
5181 }
5182 LLImageBase::setSizeOverride(TRUE);
5183 gViewerWindow->saveImageNumbered(raw);
5184 LLImageBase::setSizeOverride(FALSE);
5185 }
5186 return true;
5187 }
5188};
5189
5190class LLFileSaveMovie : public view_listener_t
5191{
5192 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5193 {
5194 LLViewerWindow::saveMovieNumbered(NULL);
5195 return true;
5196 }
5197};
5198
5199class LLFileSetWindowSize : public view_listener_t
5200{
5201 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5202 {
5203 LLString size = userdata.asString();
5204 S32 width, height;
5205 sscanf(size.c_str(), "%d,%d", &width, &height);
5206 LLViewerWindow::movieSize(width, height);
5207 return true;
5208 }
5209};
5210
5211class LLFileQuit : public view_listener_t
5212{
5213 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
5214 {
5215 app_request_quit();
5216 return true;
5217 }
5218};
5219
5220void handle_upload(void* data)
5221{
5222 const char* filename = upload_pick(data);
5223 if (filename)
5224 {
5225 LLFloaterNameDesc* floaterp = new LLFloaterNameDesc(filename);
5226 gUICtrlFactory->buildFloater(floaterp, "floater_name_description.xml");
5227 }
5228}
5229
5230void handle_compress_image(void*)
5231{
5232 LLFilePicker& picker = LLFilePicker::instance();
5233 if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE))
5234 {
5235 std::string infile(picker.getFirstFile());
5236 std::string outfile = infile + ".j2c";
5237
5238 llinfos << "Input: " << infile << llendl;
5239 llinfos << "Output: " << outfile << llendl;
5240
5241 BOOL success;
5242
5243 success = LLViewerImageList::createUploadFile(infile, outfile, IMG_CODEC_TGA);
5244
5245 if (success)
5246 {
5247 llinfos << "Compression complete" << llendl;
5248 }
5249 else
5250 {
5251 llinfos << "Compression failed: " << LLImageBase::getLastError() << llendl;
5252 }
5253 }
5254}
5255
5256void upload_new_resource(const LLString& src_filename, std::string name,
5257 std::string desc, S32 compression_info,
5258 LLAssetType::EType destination_folder_type,
5259 LLInventoryType::EType inv_type,
5260 U32 next_owner_perm,
5261 const LLString& display_name,
5262 LLAssetStorage::LLStoreAssetCallback callback,
5263 void *userdata)
5264{
5265 // Generate the temporary UUID.
5266 LLString filename = gDirUtilp->getTempFilename();
5267 LLTransactionID tid;
5268 LLAssetID uuid;
5269
5270 LLStringBase<char>::format_map_t args;
5271
5272 LLString ext = src_filename.substr(src_filename.find_last_of('.'));
5273 LLAssetType::EType asset_type = LLAssetType::AT_NONE;
5274 char error_message[MAX_STRING]; /* Flawfinder: ignore */
5275 error_message[0] = '\0';
5276 LLString temp_str;
5277
5278 BOOL error = FALSE;
5279
5280 if (ext.empty())
5281 {
5282 LLString::size_type offset = filename.find_last_of(gDirUtilp->getDirDelimiter());
5283 if (offset != LLString::npos)
5284 offset++;
5285 LLString short_name = filename.substr(offset);
5286
5287 // No extension
5288 snprintf(error_message, /* Flawfinder: ignore */
5289 MAX_STRING,
5290 "No file extension for the file: '%s'\nPlease make sure the file has a correct file extension",
5291 short_name.c_str());
5292 args["[FILE]"] = short_name;
5293 upload_error(error_message, "NofileExtension", filename, args);
5294 return;
5295 }
5296 else if( LLString::compareInsensitive(ext.c_str(),".bmp") == 0 )
5297 {
5298 asset_type = LLAssetType::AT_TEXTURE;
5299 if (!LLViewerImageList::createUploadFile(src_filename,
5300 filename,
5301 IMG_CODEC_BMP ))
5302 {
5303 snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */
5304 src_filename.c_str(), LLImageBase::getLastError().c_str());
5305 args["[FILE]"] = src_filename;
5306 args["[ERROR]"] = LLImageBase::getLastError();
5307 upload_error(error_message, "ProblemWithFile", filename, args);
5308 return;
5309 }
5310 }
5311 else if( LLString::compareInsensitive(ext.c_str(),".tga") == 0 )
5312 {
5313 asset_type = LLAssetType::AT_TEXTURE;
5314 if (!LLViewerImageList::createUploadFile(src_filename,
5315 filename,
5316 IMG_CODEC_TGA ))
5317 {
5318 snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */
5319 src_filename.c_str(), LLImageBase::getLastError().c_str());
5320 args["[FILE]"] = src_filename;
5321 args["[ERROR]"] = LLImageBase::getLastError();
5322 upload_error(error_message, "ProblemWithFile", filename, args);
5323 return;
5324 }
5325 }
5326 else if( LLString::compareInsensitive(ext.c_str(),".jpg") == 0 || LLString::compareInsensitive(ext.c_str(),".jpeg") == 0)
5327 {
5328 asset_type = LLAssetType::AT_TEXTURE;
5329 if (!LLViewerImageList::createUploadFile(src_filename,
5330 filename,
5331 IMG_CODEC_JPEG ))
5332 {
5333 snprintf(error_message, MAX_STRING, "Problem with file %s:\n\n%s\n", /* Flawfinder: ignore */
5334 src_filename.c_str(), LLImageBase::getLastError().c_str());
5335 args["[FILE]"] = src_filename;
5336 args["[ERROR]"] = LLImageBase::getLastError();
5337 upload_error(error_message, "ProblemWithFile", filename, args);
5338 return;
5339 }
5340 }
5341 else if(LLString::compareInsensitive(ext.c_str(),".wav") == 0)
5342 {
5343 asset_type = LLAssetType::AT_SOUND; // tag it as audio
5344 S32 encode_result = 0;
5345
5346 S32 bitrate = 128;
5347
5348 if (compression_info)
5349 {
5350 bitrate = compression_info;
5351 }
5352 llinfos << "Attempting to encode wav as an ogg file at " << bitrate << "kbps" << llendl;
5353
5354 encode_result = encode_vorbis_file_at(src_filename.c_str(), filename.c_str(), bitrate*1000);
5355
5356 if (LLVORBISENC_NOERR != encode_result)
5357 {
5358 switch(encode_result)
5359 {
5360 case LLVORBISENC_DEST_OPEN_ERR:
5361 snprintf(error_message, MAX_STRING, "Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str()); /* Flawfinder: ignore */
5362 args["[FILE]"] = filename;
5363 upload_error(error_message, "CannotOpenTemporarySoundFile", filename, args);
5364 break;
5365
5366 default:
5367 snprintf(error_message, MAX_STRING, "Unknown vorbis encode failure on: %s\n", src_filename.c_str()); /* Flawfinder: ignore */
5368 args["[FILE]"] = src_filename;
5369 upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args);
5370 break;
5371 }
5372 return;
5373 }
5374 }
5375 else if(LLString::compareInsensitive(ext.c_str(),".tmp") == 0)
5376 {
5377 // This is a generic .lin resource file
5378 asset_type = LLAssetType::AT_OBJECT;
5379 FILE* in = LLFile::fopen(src_filename.c_str(), "rb"); /* Flawfinder: ignore */
5380 if (in)
5381 {
5382 // read in the file header
5383 char buf[16384]; /* Flawfinder: ignore */
5384 S32 read; /* Flawfinder: ignore */
5385 S32 version;
5386 if (fscanf(in, "LindenResource\nversion %d\n", &version))
5387 {
5388 if (2 == version)
5389 {
5390 // *NOTE: This buffer size is hard coded into scanf() below.
5391 char label[MAX_STRING]; /* Flawfinder: ignore */
5392 char value[MAX_STRING]; /* Flawfinder: ignore */
5393 S32 tokens_read;
5394 while (fgets(buf, 1024, in))
5395 {
5396 label[0] = '\0';
5397 value[0] = '\0';
5398 tokens_read = sscanf( /* Flawfinder: ignore */
5399 buf,
5400 "%254s %254s\n",
5401 label, value);
5402
5403 llinfos << "got: " << label << " = " << value
5404 << llendl;
5405
5406 if (EOF == tokens_read)
5407 {
5408 fclose(in);
5409 snprintf(error_message, MAX_STRING, "corrupt resource file: %s", src_filename.c_str()); /* Flawfinder: ignore */
5410 args["[FILE]"] = src_filename;
5411 upload_error(error_message, "CorruptResourceFile", filename, args);
5412 return;
5413 }
5414
5415 if (2 == tokens_read)
5416 {
5417 if (! strcmp("type", label))
5418 {
5419 asset_type = (LLAssetType::EType)(atoi(value));
5420 }
5421 }
5422 else
5423 {
5424 if (! strcmp("_DATA_", label))
5425 {
5426 // below is the data section
5427 break;
5428 }
5429 }
5430 // other values are currently discarded
5431 }
5432
5433 }
5434 else
5435 {
5436 fclose(in);
5437 snprintf(error_message, MAX_STRING, "unknown linden resource file version in file: %s", src_filename.c_str()); /* Flawfinder: ignore */
5438 args["[FILE]"] = src_filename;
5439 upload_error(error_message, "UnknownResourceFileVersion", filename, args);
5440 return;
5441 }
5442 }
5443 else
5444 {
5445 // this is an original binary formatted .lin file
5446 // start over at the beginning of the file
5447 fseek(in, 0, SEEK_SET);
5448
5449 const S32 MAX_ASSET_DESCRIPTION_LENGTH = 256;
5450 const S32 MAX_ASSET_NAME_LENGTH = 64;
5451 S32 header_size = 34 + MAX_ASSET_DESCRIPTION_LENGTH + MAX_ASSET_NAME_LENGTH;
5452 S16 type_num;
5453
5454 // read in and throw out most of the header except for the type
5455 fread(buf, header_size, 1, in);
5456 memcpy(&type_num, buf + 16, sizeof(S16)); /* Flawfinder: ignore */
5457 asset_type = (LLAssetType::EType)type_num;
5458 }
5459
5460 // copy the file's data segment into another file for uploading
5461 FILE* out = LLFile::fopen(filename.c_str(), "wb"); /* Flawfinder: ignore */
5462 if (out)
5463 {
5464 while((read = fread(buf, 1, 16384, in))) /* Flawfinder: ignore */
5465 {
5466 fwrite(buf, 1, read, out); /* Flawfinder: ignore */
5467 }
5468 fclose(out);
5469 }
5470 else
5471 {
5472 fclose(in);
5473 snprintf(error_message, MAX_STRING, "Unable to create output file: %s", filename.c_str()); /* Flawfinder: ignore */
5474 args["[FILE]"] = filename;
5475 upload_error(error_message, "UnableToCreateOutputFile", filename, args);
5476 return;
5477 }
5478
5479 fclose(in);
5480 }
5481 else
5482 {
5483 llinfos << "Couldn't open .lin file " << src_filename << llendl;
5484 }
5485 }
5486 else if (LLString::compareInsensitive(ext.c_str(),".bvh") == 0)
5487 {
5488 snprintf(error_message, MAX_STRING, "We do not currently support bulk upload of animation files\n"); /* Flawfinder: ignore */
5489 upload_error(error_message, "DoNotSupportBulkAnimationUpload", filename, args);
5490 return;
5491 }
5492 else
5493 {
5494 // Unknown extension
5495 snprintf(error_message, MAX_STRING, "Unknown file extension %s\nExpected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh", ext.c_str()); /* Flawfinder: ignore */
5496 error = TRUE;;
5497 }
5498
5499 // gen a new transaction ID for this asset
5500 tid.generate();
5501
5502 if (!error)
5503 {
5504 uuid = tid.makeAssetID(gAgent.getSecureSessionID());
5505 // copy this file into the vfs for upload
5506 S32 file_size;
5507 apr_file_t* fp = ll_apr_file_open(filename, LL_APR_RB, &file_size);
5508 if (fp)
5509 {
5510 LLVFile file(gVFS, uuid, asset_type, LLVFile::WRITE);
5511
5512 file.setMaxSize(file_size);
5513
5514 const S32 buf_size = 65536;
5515 U8 copy_buf[buf_size];
5516 while ((file_size = ll_apr_file_read(fp, copy_buf, buf_size)))
5517 {
5518 file.write(copy_buf, file_size);
5519 }
5520 apr_file_close(fp);
5521 }
5522 else
5523 {
5524 snprintf(error_message, MAX_STRING, "Unable to access output file: %s", filename.c_str()); /* Flawfinder: ignore */
5525 error = TRUE;
5526 }
5527 }
5528
5529 if (!error)
5530 {
5531 LLString t_disp_name = display_name;
5532 if (t_disp_name.empty())
5533 {
5534 t_disp_name = src_filename;
5535 }
5536 upload_new_resource(tid, asset_type, name, desc, compression_info, // tid
5537 destination_folder_type, inv_type, next_owner_perm,
5538 display_name, callback, userdata);
5539 }
5540 else
5541 {
5542 llwarns << error_message << llendl;
5543 LLStringBase<char>::format_map_t args;
5544 args["[ERROR_MESSAGE]"] = error_message;
5545 gViewerWindow->alertXml("ErrorMessage", args);
5546 if(LLFile::remove(filename.c_str()) == -1)
5547 {
5548 lldebugs << "unable to remove temp file" << llendl;
5549 }
5550 LLFilePicker::instance().reset();
5551 }
5552}
5553
5554void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_type,
5555 std::string name,
5556 std::string desc, S32 compression_info,
5557 LLAssetType::EType destination_folder_type,
5558 LLInventoryType::EType inv_type,
5559 U32 next_owner_perm,
5560 const LLString& display_name,
5561 LLAssetStorage::LLStoreAssetCallback callback,
5562 void *userdata)
5563{
5564 LLAssetID uuid = tid.makeAssetID(gAgent.getSecureSessionID());
5565
5566 if( LLAssetType::AT_SOUND == asset_type )
5567 {
5568 gViewerStats->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT );
5569 }
5570 else
5571 if( LLAssetType::AT_TEXTURE == asset_type )
5572 {
5573 gViewerStats->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
5574 }
5575 else
5576 if( LLAssetType::AT_ANIMATION == asset_type)
5577 {
5578 gViewerStats->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT );
5579 }
5580
5581 if(LLInventoryType::IT_NONE == inv_type)
5582 {
5583 inv_type = LLInventoryType::defaultForAssetType(asset_type);
5584 }
5585 LLString::stripNonprintable(name);
5586 LLString::stripNonprintable(desc);
5587 if(name.empty())
5588 {
5589 name = "(No Name)";
5590 }
5591 if(desc.empty())
5592 {
5593 desc = "(No Description)";
5594 }
5595
5596 // At this point, we're ready for the upload.
5597 LLString upload_message = "Uploading...\n\n";
5598 upload_message.append(display_name);
5599 LLUploadDialog::modalUploadDialog(upload_message);
5600
5601 llinfos << "*** Uploading: " << llendl;
5602 llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl;
5603 llinfos << "UUID: " << uuid << llendl;
5604 llinfos << "Name: " << name << llendl;
5605 llinfos << "Desc: " << desc << llendl;
5606 lldebugs << "Folder: " << gInventory.findCategoryUUIDForType(destination_folder_type) << llendl;
5607 lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl;
5608 std::string url = gAgent.getRegion()->getCapability("NewFileAgentInventory");
5609 if (!url.empty())
5610 {
5611 llinfos << "New Agent Inventory via capability" << llendl;
5612 LLSD body;
5613 body["folder_id"] = gInventory.findCategoryUUIDForType((destination_folder_type == LLAssetType::AT_NONE) ? asset_type : destination_folder_type);
5614 body["asset_type"] = LLAssetType::lookup(asset_type);
5615 body["inventory_type"] = LLInventoryType::lookup(inv_type);
5616 body["name"] = name;
5617 body["description"] = desc;
5618
5619 std::ostringstream llsdxml;
5620 LLSDSerialize::toXML(body, llsdxml);
5621 lldebugs << "posting body to capability: " << llsdxml.str() << llendl;
5622 LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type));
5623 }
5624 else
5625 {
5626 llinfos << "NewAgentInventory capability not found, new agent inventory via asset system." << llendl;
5627 // check for adequate funds
5628 // TODO: do this check on the sim
5629 if (LLAssetType::AT_SOUND == asset_type ||
5630 LLAssetType::AT_TEXTURE == asset_type ||
5631 LLAssetType::AT_ANIMATION == asset_type)
5632 {
5633 S32 upload_cost = gGlobalEconomy->getPriceUpload();
5634 S32 balance = gStatusBar->getBalance();
5635 if (balance < upload_cost)
5636 {
5637 // insufficient funds, bail on this upload
5638 LLFloaterBuyCurrency::buyCurrency("Uploading costs", upload_cost);
5639 return;
5640 }
5641 }
5642
5643 LLResourceData* data = new LLResourceData;
5644 data->mAssetInfo.mTransactionID = tid;
5645 data->mAssetInfo.mUuid = uuid;
5646 data->mAssetInfo.mType = asset_type;
5647 data->mAssetInfo.mCreatorID = gAgentID;
5648 data->mInventoryType = inv_type;
5649 data->mNextOwnerPerm = next_owner_perm;
5650 data->mUserData = userdata;
5651 data->mAssetInfo.setName(name);
5652 data->mAssetInfo.setDescription(desc);
5653 data->mPreferredLocation = destination_folder_type;
5654
5655 LLAssetStorage::LLStoreAssetCallback asset_callback = &upload_done_callback;
5656 if (callback)
5657 {
5658 asset_callback = callback;
5659 }
5660 gAssetStorage->storeAssetData(data->mAssetInfo.mTransactionID, data->mAssetInfo.mType,
5661 asset_callback,
5662 (void*)data,
5663 FALSE);
5664 }
5665}
5666
5667void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result) // StoreAssetData callback (fixed)
5668{
5669 LLResourceData* data = (LLResourceData*)user_data;
5670 //LLAssetType::EType pref_loc = data->mPreferredLocation;
5671 BOOL is_balance_sufficient = TRUE;
5672 if(result >= 0)
5673 {
5674 LLAssetType::EType dest_loc = (data->mPreferredLocation == LLAssetType::AT_NONE) ? data->mAssetInfo.mType : data->mPreferredLocation;
5675
5676 if (LLAssetType::AT_SOUND == data->mAssetInfo.mType ||
5677 LLAssetType::AT_TEXTURE == data->mAssetInfo.mType ||
5678 LLAssetType::AT_ANIMATION == data->mAssetInfo.mType)
5679 {
5680 // Charge the user for the upload.
5681 LLViewerRegion* region = gAgent.getRegion();
5682 S32 upload_cost = gGlobalEconomy->getPriceUpload();
5683
5684 if(!(can_afford_transaction(upload_cost)))
5685 {
5686 LLFloaterBuyCurrency::buyCurrency(
5687 llformat("Uploading %s costs",
5688 data->mAssetInfo.getName().c_str()),
5689 upload_cost);
5690 is_balance_sufficient = FALSE;
5691 }
5692 else if(region)
5693 {
5694 // Charge user for upload
5695 gStatusBar->debitBalance(upload_cost);
5696
5697 LLMessageSystem* msg = gMessageSystem;
5698 msg->newMessageFast(_PREHASH_MoneyTransferRequest);
5699 msg->nextBlockFast(_PREHASH_AgentData);
5700 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
5701 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
5702 msg->nextBlockFast(_PREHASH_MoneyData);
5703 msg->addUUIDFast(_PREHASH_SourceID, gAgent.getID());
5704 msg->addUUIDFast(_PREHASH_DestID, LLUUID::null);
5705 msg->addU8("Flags", 0);
5706 msg->addS32Fast(_PREHASH_Amount, upload_cost);
5707 msg->addU8Fast(_PREHASH_AggregatePermNextOwner, (U8)LLAggregatePermissions::AP_EMPTY);
5708 msg->addU8Fast(_PREHASH_AggregatePermInventory, (U8)LLAggregatePermissions::AP_EMPTY);
5709 msg->addS32Fast(_PREHASH_TransactionType, TRANS_UPLOAD_CHARGE);
5710 msg->addStringFast(_PREHASH_Description, NULL);
5711 msg->sendReliable(region->getHost());
5712 }
5713 }
5714
5715 if(is_balance_sufficient)
5716 {
5717 // Actually add the upload to inventory
5718 llinfos << "Adding " << uuid << " to inventory." << llendl;
5719 LLUUID folder_id(gInventory.findCategoryUUIDForType(dest_loc));
5720 if(folder_id.notNull())
5721 {
5722 U32 next_owner_perm = data->mNextOwnerPerm;
5723 if(PERM_NONE == next_owner_perm)
5724 {
5725 next_owner_perm = PERM_MOVE | PERM_TRANSFER;
5726 }
5727 create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
5728 folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(),
5729 data->mAssetInfo.getDescription(), data->mAssetInfo.mType,
5730 data->mInventoryType, NOT_WEARABLE, next_owner_perm,
5731 LLPointer<LLInventoryCallback>(NULL));
5732 }
5733 else
5734 {
5735 llwarns << "Can't find a folder to put it in" << llendl;
5736 }
5737 }
5738 }
5739 else // if(result >= 0)
5740 {
5741 LLStringBase<char>::format_map_t args;
5742 args["[FILE]"] = LLInventoryType::lookupHumanReadable(data->mInventoryType);
5743 args["[REASON]"] = LLString(LLAssetStorage::getErrorString(result));
5744 gViewerWindow->alertXml("CannotUploadReason", args);
5745 }
5746
5747 LLUploadDialog::modalUploadFinished();
5748 delete data;
5749
5750 // *NOTE: This is a pretty big hack. What this does is check the
5751 // file picker if there are any more pending uploads. If so,
5752 // upload that file.
5753 const char* next_file = LLFilePicker::instance().getNextFile();
5754 if(is_balance_sufficient && next_file)
5755 {
5756 const char* name = LLFilePicker::instance().getDirname();
5757
5758 LLString asset_name = name;
5759 LLString::replaceNonstandardASCII( asset_name, '?' );
5760 LLString::replaceChar(asset_name, '|', '?');
5761 LLString::stripNonprintable(asset_name);
5762 LLString::trim(asset_name);
5763
5764 char* asset_name_str = (char*)asset_name.c_str();
5765 char* end_p = strrchr(asset_name_str, '.'); // strip extension if exists
5766 if( !end_p )
5767 {
5768 end_p = asset_name_str + strlen( asset_name_str ); /* Flawfinder: ignore */
5769 }
5770
5771 S32 len = llmin( (S32) (DB_INV_ITEM_NAME_STR_LEN), (S32) (end_p - asset_name_str) );
5772
5773 asset_name = asset_name.substr( 0, len );
5774
5775 upload_new_resource(next_file, asset_name, asset_name, // file
5776 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE);
5777 }
5778}
5779 4871
5780LLUUID gExporterRequestID; 4872LLUUID gExporterRequestID;
5781LLString gExportDirectory; 4873LLString gExportDirectory;
@@ -7634,15 +6726,6 @@ BOOL enable_not_thirdperson(void*)
7634 return !gAgent.cameraThirdPerson(); 6726 return !gAgent.cameraThirdPerson();
7635} 6727}
7636 6728
7637class LLFileEnableUpload : public view_listener_t
7638{
7639 bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
7640 {
7641 bool new_value = gStatusBar && gGlobalEconomy && (gStatusBar->getBalance() >= gGlobalEconomy->getPriceUpload());
7642 gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
7643 return true;
7644 }
7645};
7646 6729
7647BOOL enable_export_selected(void *) 6730BOOL enable_export_selected(void *)
7648{ 6731{
@@ -7857,14 +6940,6 @@ void reload_vertex_shader(void *)
7857 //THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought - DaveP 6940 //THIS WOULD BE AN AWESOME PLACE TO RELOAD SHADERS... just a thought - DaveP
7858} 6941}
7859 6942
7860void flush_animations(void *)
7861{
7862 if (gAgent.getAvatarObject())
7863 {
7864 gAgent.getAvatarObject()->resetAnimations();
7865 }
7866}
7867
7868void slow_mo_animations(void*) 6943void slow_mo_animations(void*)
7869{ 6944{
7870 static BOOL slow_mo = FALSE; 6945 static BOOL slow_mo = FALSE;
@@ -8450,24 +7525,10 @@ class LLToolsSelectTool : public view_listener_t
8450 } 7525 }
8451}; 7526};
8452 7527
8453void initialize_menu_actions() 7528void initialize_menus()
8454{ 7529{
8455 // File menu 7530 // File menu
8456 (new LLFileUploadImage())->registerListener(gMenuHolder, "File.UploadImage"); 7531 init_menu_file();
8457 (new LLFileUploadSound())->registerListener(gMenuHolder, "File.UploadSound");
8458 (new LLFileUploadAnim())->registerListener(gMenuHolder, "File.UploadAnim");
8459 (new LLFileUploadBulk())->registerListener(gMenuHolder, "File.UploadBulk");
8460 (new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow");
8461 (new LLFileEnableCloseWindow())->registerListener(gMenuHolder, "File.EnableCloseWindow");
8462 (new LLFileSaveTexture())->registerListener(gMenuHolder, "File.SaveTexture");
8463 (new LLFileTakeSnapshot())->registerListener(gMenuHolder, "File.TakeSnapshot");
8464 (new LLFileTakeSnapshotToDisk())->registerListener(gMenuHolder, "File.TakeSnapshotToDisk");
8465 (new LLFileSaveMovie())->registerListener(gMenuHolder, "File.SaveMovie");
8466 (new LLFileSetWindowSize())->registerListener(gMenuHolder, "File.SetWindowSize");
8467 (new LLFileQuit())->registerListener(gMenuHolder, "File.Quit");
8468
8469 (new LLFileEnableUpload())->registerListener(gMenuHolder, "File.EnableUpload");
8470 (new LLFileEnableSaveAs())->registerListener(gMenuHolder, "File.EnableSaveAs");
8471 7532
8472 // Edit menu 7533 // Edit menu
8473 (new LLEditUndo())->registerListener(gMenuHolder, "Edit.Undo"); 7534 (new LLEditUndo())->registerListener(gMenuHolder, "Edit.Undo");