diff -r a1319d553db9 -r fb7cbd40e03c doc/contributions.txt --- a/doc/contributions.txt Wed Nov 16 14:02:34 2011 -0500 +++ b/doc/contributions.txt Wed Jan 04 15:16:35 2012 +0000 @@ -482,6 +482,7 @@ OPEN-76 STORM-959 STORM-1175 + STORM-1708 Imnotgoing Sideways Inma Rau Innula Zenovka diff -r a1319d553db9 -r fb7cbd40e03c indra/llui/lltexteditor.h --- a/indra/llui/lltexteditor.h Wed Nov 16 14:02:34 2011 -0500 +++ b/indra/llui/lltexteditor.h Wed Jan 04 15:16:35 2012 +0000 @@ -92,6 +92,8 @@ void setParseHighlights(BOOL parsing) {mParseHighlights=parsing;} + static S32 spacesPerTab(); + // mousehandler overrides virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); @@ -140,6 +142,8 @@ virtual void selectAll(); virtual BOOL canSelectAll() const; + virtual bool canLoadOrSaveToFile(); + void selectNext(const std::string& search_text_in, BOOL case_insensitive, BOOL wrap = TRUE); BOOL replaceText(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive, BOOL wrap = TRUE); void replaceTextAll(const std::string& search_text, const std::string& replace_text, BOOL case_insensitive); @@ -158,6 +162,7 @@ // inserts text at cursor void insertText(const std::string &text); + void insertText(LLWString &text); void appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo); // Non-undoable diff -r a1319d553db9 -r fb7cbd40e03c indra/llui/lltexteditor.cpp --- a/indra/llui/lltexteditor.cpp Wed Nov 16 14:02:34 2011 -0500 +++ b/indra/llui/lltexteditor.cpp Wed Jan 04 15:16:35 2012 +0000 @@ -2250,6 +2250,22 @@ setEnabled( enabled ); } +void LLTextEditor::insertText(LLWString &new_text) +{ + BOOL enabled = getEnabled(); + setEnabled( TRUE ); + + // Delete any selected characters (the insertion replaces them) + if( hasSelection() ) + { + deleteSelection(TRUE); + } + + setCursorPos(mCursorPos + insert( mCursorPos, new_text, FALSE, LLTextSegmentPtr() )); + + setEnabled( enabled ); +} + void LLTextEditor::appendWidget(const LLInlineViewSegment::Params& params, const std::string& text, bool allow_undo) { // Save old state @@ -2838,3 +2854,13 @@ getViewModel()->setDisplay(LLWStringUtil::null); clearSegments(); } + +bool LLTextEditor::canLoadOrSaveToFile() +{ + return !mReadOnly; +} + +S32 LLTextEditor::spacesPerTab() +{ + return SPACES_PER_TAB; +} diff -r a1319d553db9 -r fb7cbd40e03c indra/newview/llfilepicker.h --- a/indra/newview/llfilepicker.h Wed Nov 16 14:02:34 2011 -0500 +++ b/indra/newview/llfilepicker.h Wed Jan 04 15:16:35 2012 +0000 @@ -84,6 +84,7 @@ FFLOAD_RAW = 8, FFLOAD_MODEL = 9, FFLOAD_COLLADA = 10, + FFLOAD_SCRIPT = 11, }; enum ESaveFilter @@ -103,6 +104,7 @@ FFSAVE_J2C = 12, FFSAVE_PNG = 13, FFSAVE_JPEG = 14, + FFSAVE_SCRIPT = 15, }; // open the dialog. This is a modal operation diff -r a1319d553db9 -r fb7cbd40e03c indra/newview/llfilepicker.cpp --- a/indra/newview/llfilepicker.cpp Wed Nov 16 14:02:34 2011 -0500 +++ b/indra/newview/llfilepicker.cpp Wed Jan 04 15:16:35 2012 +0000 @@ -58,6 +58,7 @@ #define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0" #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0" #define MODEL_FILTER L"Model files (*.dae)\0*.dae\0" +#define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0" #endif // @@ -213,6 +214,10 @@ mOFN.lpstrFilter = MODEL_FILTER \ L"\0"; break; + case FFLOAD_SCRIPT: + mOFN.lpstrFilter = SCRIPT_FILTER \ + L"\0"; + break; default: res = FALSE; break; @@ -497,6 +502,14 @@ L"Compressed Images (*.j2c)\0*.j2c\0" \ L"\0"; break; + case FFSAVE_SCRIPT: + if (filename.empty()) + { + wcsncpy( mFilesW,L"untitled.lsl", FILENAME_BUFFER_SIZE); + } + mOFN.lpstrDefExt = L"txt"; + mOFN.lpstrFilter = L"LSL Files (*.lsl)\0*.lsl\0" L"\0"; + break; default: return FALSE; } @@ -620,6 +633,14 @@ result = false; } } + else if (filter == FFLOAD_SCRIPT) + { + if (fileInfo.filetype != 'LSL ' && + (fileInfo.extension && (CFStringCompare(fileInfo.extension, CFSTR("lsl"), kCFCompareCaseInsensitive) != kCFCompareEqualTo)) ) + { + result = false; + } + } if (fileInfo.extension) { @@ -766,6 +787,12 @@ extension = CFSTR(".j2c"); break; + case FFSAVE_SCRIPT: + type = 'LSL '; + creator = '\?\?\?\?'; + extension = CFSTR(".lsl"); + break; + case FFSAVE_ALL: default: type = '\?\?\?\?'; @@ -1192,7 +1219,12 @@ add_common_filters_to_gtkchooser(gfilter, picker, filtername); return filtername; } - + +static std::string add_script_filter_to_gtkchooser(GtkWindow *picker) +{ + return add_simple_mime_filter_to_gtkchooser(picker, "text/plain", + LLTrans::getString("script_files") + " (*.lsl)"); +} BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename ) { @@ -1258,6 +1290,10 @@ LLTrans::getString("compressed_image_files") + " (*.j2c)"); suggest_ext = ".j2c"; break; + case FFSAVE_SCRIPT: + caption += add_script_filter_to_gtkchooser(picker); + suggest_ext = ".lsl"; + break; default:; break; } @@ -1323,6 +1359,9 @@ case FFLOAD_IMAGE: filtername = add_imageload_filter_to_gtkchooser(picker); break; + case FFLOAD_SCRIPT: + filtername = add_script_filter_to_gtkchooser(picker); + break; default:; break; } diff -r a1319d553db9 -r fb7cbd40e03c indra/newview/llfloaternamedesc.h --- a/indra/newview/llfloaternamedesc.h Wed Nov 16 14:02:34 2011 -0500 +++ b/indra/newview/llfloaternamedesc.h Wed Jan 04 15:16:35 2012 +0000 @@ -51,6 +51,7 @@ protected: BOOL mIsAudio; + bool mIsText; std::string mFilenameAndPath; std::string mFilename; @@ -62,5 +63,12 @@ LLFloaterSoundPreview(const LLSD& filename ); virtual BOOL postBuild(); }; - + +class LLFloaterScriptPreview : public LLFloaterNameDesc +{ +public: + LLFloaterScriptPreview(const LLSD& filename ); + virtual BOOL postBuild(); +}; + #endif // LL_LLFLOATERNAMEDESC_H diff -r a1319d553db9 -r fb7cbd40e03c indra/newview/llfloaternamedesc.cpp --- a/indra/newview/llfloaternamedesc.cpp Wed Nov 16 14:02:34 2011 -0500 +++ b/indra/newview/llfloaternamedesc.cpp Wed Jan 04 15:16:35 2012 +0000 @@ -204,3 +204,24 @@ getChild("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this)); return TRUE; } + + +//----------------------------------------------------------------------------- +// LLFloaterScriptPreview() +//----------------------------------------------------------------------------- + +LLFloaterScriptPreview::LLFloaterScriptPreview(const LLSD& filename ) + : LLFloaterNameDesc(filename) +{ + mIsText = TRUE; +} + +BOOL LLFloaterScriptPreview::postBuild() +{ + if (!LLFloaterNameDesc::postBuild()) + { + return FALSE; + } + getChild("ok_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnOK, this)); + return TRUE; +} diff -r a1319d553db9 -r fb7cbd40e03c indra/newview/llpreviewscript.h --- a/indra/newview/llpreviewscript.h Wed Nov 16 14:02:34 2011 -0500 +++ b/indra/newview/llpreviewscript.h Wed Jan 04 15:16:35 2012 +0000 @@ -79,6 +79,7 @@ /*virtual*/ BOOL postBuild(); BOOL canClose(); void setEnableEditing(bool enable); + bool canLoadOrSaveToFile( void* userdata ); void setScriptText(const std::string& text, BOOL is_valid); bool loadScriptText(const std::string& filename); @@ -98,6 +99,11 @@ static void onClickForward(void* userdata); static void onBtnInsertSample(void*); static void onBtnInsertFunction(LLUICtrl*, void*); + static void onBtnLoadFromFile(void*); + static void onBtnSaveToFile(void*); + + static bool enableSaveToFileMenu(void* userdata); + static bool enableLoadFromFileMenu(void* userdata); virtual bool hasAccelerators() const { return true; } diff -r a1319d553db9 -r fb7cbd40e03c indra/newview/llpreviewscript.cpp --- a/indra/newview/llpreviewscript.cpp Wed Nov 16 14:02:34 2011 -0500 +++ b/indra/newview/llpreviewscript.cpp Wed Jan 04 15:16:35 2012 +0000 @@ -35,6 +35,7 @@ #include "llcombobox.h" #include "lldir.h" #include "llexternaleditor.h" +#include "llfilepicker.h" #include "llfloaterreg.h" #include "llinventorydefines.h" #include "llinventorymodel.h" @@ -503,6 +504,14 @@ menuItem = getChild("Keyword Help..."); menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnDynamicHelp, this)); + + menuItem = getChild("LoadFromFile"); + menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnLoadFromFile, this)); + menuItem->setEnableCallback(boost::bind(&LLScriptEdCore::enableLoadFromFileMenu, this)); + + menuItem = getChild("SaveToFile"); + menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnSaveToFile, this)); + menuItem->setEnableCallback(boost::bind(&LLScriptEdCore::enableSaveToFileMenu, this)); } void LLScriptEdCore::setScriptText(const std::string& text, BOOL is_valid) @@ -1096,6 +1105,88 @@ return FALSE; } +void LLScriptEdCore::onBtnLoadFromFile( void* data ) +{ + LLScriptEdCore* self = (LLScriptEdCore*) data; + + // TODO Maybe add a dialogue warning here if the current file has unsaved changes. + LLFilePicker& file_picker = LLFilePicker::instance(); + if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_SCRIPT ) ) + { + //File picking cancelled by user, so nothing to do. + return; + } + + std::string filename = file_picker.getFirstFile(); + + std::ifstream fin(filename.c_str()); + + std::string line; + std::string text; + std::string linetotal; + while (!fin.eof()) + { + getline(fin,line); + text += line; + if (!fin.eof()) + { + text += "\n"; + } + } + fin.close(); + + // Only replace the script if there is something to replace with. + if (text.length() > 0) + { + self->mEditor->selectAll(); + LLWString script(utf8str_to_wstring(text)); + self->mEditor->insertText(script); + } +} + +void LLScriptEdCore::onBtnSaveToFile( void* userdata ) +{ + + LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT ); + + LLScriptEdCore* self = (LLScriptEdCore*) userdata; + + if( self->mSaveCallback ) + { + LLFilePicker& file_picker = LLFilePicker::instance(); + if( file_picker.getSaveFile( LLFilePicker::FFSAVE_SCRIPT ) ) + { + std::string filename = file_picker.getFirstFile(); + std::string scriptText=self->mEditor->getText(); + std::ofstream fout(filename.c_str()); + fout<<(scriptText); + fout.close(); + self->mSaveCallback( self->mUserdata, FALSE ); + } + } +} + +bool LLScriptEdCore::canLoadOrSaveToFile( void* userdata ) +{ + LLScriptEdCore* self = (LLScriptEdCore*) userdata; + return self->mEditor->canLoadOrSaveToFile(); +} + +// static +bool LLScriptEdCore::enableSaveToFileMenu(void* userdata) +{ + LLScriptEdCore* self = (LLScriptEdCore*)userdata; + if (!self || !self->mEditor) return FALSE; + return self->mEditor->canLoadOrSaveToFile(); +} + +// static +bool LLScriptEdCore::enableLoadFromFileMenu(void* userdata) +{ + LLScriptEdCore* self = (LLScriptEdCore*)userdata; + return (self && self->mEditor) ? self->mEditor->canLoadOrSaveToFile() : FALSE; +} + /// --------------------------------------------------------------------------- /// LLScriptEdContainer /// --------------------------------------------------------------------------- diff -r a1319d553db9 -r fb7cbd40e03c indra/newview/llviewerfloaterreg.cpp --- a/indra/newview/llviewerfloaterreg.cpp Wed Nov 16 14:02:34 2011 -0500 +++ b/indra/newview/llviewerfloaterreg.cpp Wed Jan 04 15:16:35 2012 +0000 @@ -292,9 +292,10 @@ LLFloaterUIPreviewUtil::registerFloater(); LLFloaterReg::add("upload_anim", "floater_animation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); LLFloaterReg::add("upload_image", "floater_image_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); - LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); LLFloaterReg::add("upload_model", "floater_model_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); LLFloaterReg::add("upload_model_wizard", "floater_model_wizard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("upload_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); + LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build, "upload"); LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); diff -r a1319d553db9 -r fb7cbd40e03c indra/newview/skins/default/xui/en/panel_script_ed.xml --- a/indra/newview/skins/default/xui/en/panel_script_ed.xml Wed Nov 16 14:02:34 2011 -0500 +++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml Wed Jan 04 15:16:35 2012 +0000 @@ -54,12 +54,22 @@ label="Save" layout="topleft" name="Save" /> - - + + + + + Second Life logins are temporarily restricted in order to make sure that those in-world have the best possible experience. - + People with free accounts will not be able to access Second Life during this time, to make room for those who have paid for Second Life. Second Life cannot be accessed from this computer. If you feel this is an error, please contact @@ -168,7 +168,7 @@ You are wearing one or more of these objects. Remove them from your avatar and try moving them again. This folder has too many levels of subfolders. Rearrange the interior folders to a maximum of 4 levels deep (Root Folder contains A contains B contains C). This folder contains more than 200 objects. Box some of the items to reduce the object count. - + Click to view this web page Click to view this location's information @@ -188,7 +188,7 @@ Click to view this object's description Click to view this location on a map Click to run the secondlife:// command - + Teleport to @@ -427,9 +427,10 @@ Compressed Images Load Files Choose Directory + Scripts - - + Sleeps script for [SLEEP_TIME] seconds. @@ -1950,7 +1951,7 @@ Physics invalid none - + Shirt not worn Pants not worn @@ -1987,7 +1988,7 @@ New [WEARABLE_ITEM] - + Next @@ -2313,7 +2314,7 @@ Error: script information is only available in your current region Retrieving information... You do not have permission to examine this parcel - + Sitting On Chest Head @@ -2353,7 +2354,7 @@ HUD Bottom Left HUD Bottom HUD Bottom Right - + Line [LINE], Column [COLUMN] @@ -2366,7 +2367,7 @@ Content of object - New Script + New Script The Resident you messaged is in 'busy mode' which means they have requested not to be disturbed. Your message will still be shown in their IM panel for later viewing. @@ -2396,7 +2397,7 @@ Clicks: [TELEPORT] teleport, [MAP] map, [PROFILE] profile (will update after publish) - + You haven't created any Picks or Classifieds. Click the Plus button below to create a Pick or Classified. User has no picks or classifieds @@ -3273,7 +3274,7 @@ You have blocked this Resident. Sending a message will automatically unblock them. @@ -3299,7 +3300,7 @@ You are not a session moderator. @@ -3312,12 +3313,12 @@ Unable to add users to chat session with [RECIPIENT]. Unable to send your message to the chat session with [RECIPIENT]. - + Unable to send your message to the chat session with [RECIPIENT]. @@ -3325,7 +3326,7 @@ Error while moderating. @@ -3346,9 +3347,9 @@ The session initialization is timed out - + Home position set. - + http://secondlife.com/landing/voicemorphing @@ -3366,20 +3367,20 @@ to join a group to upload to publish a classified ad - + Giving L$ [AMOUNT] Uploading costs L$ [AMOUNT] This costs L$ [AMOUNT] Buying selected land for L$ [AMOUNT] This object costs L$ [AMOUNT] - + Everyone Officers Owners Online Uploading... - + Abuse Report @@ -3473,23 +3474,23 @@ [mthnum,datetime,slt]/[day,datetime,slt]/[year,datetime,slt] - + none/none Can't load images larger than [WIDTH]*[HEIGHT] - + Despite our best efforts, something unexpected has gone wrong. - Please check status.secondlifegrid.net to see if there is a known problem with the service. + Please check status.secondlifegrid.net to see if there is a known problem with the service. If you continue to experience problems, please check your network and firewall setup. - Sunday:Monday:Tuesday:Wednesday:Thursday:Friday:Saturday Sun:Mon:Tue:Wed:Thu:Fri:Sat @@ -3522,7 +3523,7 @@ Delete selected item? There are no items in this outfit - + Select an editor using the ExternalEditor setting. Cannot find the external editor you specified.