diff options
-rw-r--r-- | linden/indra/newview/app_settings/settings.xml | 11 | ||||
-rw-r--r-- | linden/indra/newview/llfilepicker.cpp | 24 | ||||
-rw-r--r-- | linden/indra/newview/llfilepicker.h | 1 | ||||
-rw-r--r-- | linden/indra/newview/llpreviewscript.cpp | 284 | ||||
-rw-r--r-- | linden/indra/newview/llpreviewscript.h | 17 | ||||
-rw-r--r-- | linden/indra/newview/skins/default/xui/en-us/floater_live_lsleditor.xml | 2 | ||||
-rw-r--r-- | linden/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml | 14 |
7 files changed, 341 insertions, 12 deletions
diff --git a/linden/indra/newview/app_settings/settings.xml b/linden/indra/newview/app_settings/settings.xml index 3279b6b..439459c 100644 --- a/linden/indra/newview/app_settings/settings.xml +++ b/linden/indra/newview/app_settings/settings.xml | |||
@@ -795,6 +795,17 @@ | |||
795 | <key>Value</key> | 795 | <key>Value</key> |
796 | <integer>30</integer> | 796 | <integer>30</integer> |
797 | </map> | 797 | </map> |
798 | <key>LSLExternalEditor</key> | ||
799 | <map> | ||
800 | <key>Comment</key> | ||
801 | <string>Controls the location of the External editor</string> | ||
802 | <key>Persist</key> | ||
803 | <integer>1</integer> | ||
804 | <key>Type</key> | ||
805 | <string>String</string> | ||
806 | <key>Value</key> | ||
807 | <string /> | ||
808 | </map> | ||
798 | <key>MapServerURL</key> | 809 | <key>MapServerURL</key> |
799 | <map> | 810 | <map> |
800 | <key>Comment</key> | 811 | <key>Comment</key> |
diff --git a/linden/indra/newview/llfilepicker.cpp b/linden/indra/newview/llfilepicker.cpp index ec4e294..a562b17 100644 --- a/linden/indra/newview/llfilepicker.cpp +++ b/linden/indra/newview/llfilepicker.cpp | |||
@@ -60,6 +60,12 @@ LLFilePicker LLFilePicker::sInstance; | |||
60 | #define XML_FILTER L"XML files (*.xml)\0*.xml\0" | 60 | #define XML_FILTER L"XML files (*.xml)\0*.xml\0" |
61 | #define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0" | 61 | #define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0" |
62 | #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0" | 62 | #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0" |
63 | #ifdef LL_WINDOWS | ||
64 | #define APP_FILTER L"Executable files (*.exe)\0*.exe\0" | ||
65 | #else | ||
66 | // If we can, add any mac/linux binary searching here -- MC | ||
67 | #define APP_FILTER L"Executable files (*.*)\0*.*\0" | ||
68 | #endif // LL_WINDOOWS | ||
63 | #endif | 69 | #endif |
64 | 70 | ||
65 | // | 71 | // |
@@ -192,6 +198,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter) | |||
192 | mOFN.lpstrFilter = RAW_FILTER \ | 198 | mOFN.lpstrFilter = RAW_FILTER \ |
193 | L"\0"; | 199 | L"\0"; |
194 | break; | 200 | break; |
201 | case FFLOAD_APP: | ||
202 | mOFN.lpstrFilter = APP_FILTER \ | ||
203 | L"\0"; | ||
204 | break; | ||
195 | default: | 205 | default: |
196 | res = FALSE; | 206 | res = FALSE; |
197 | break; | 207 | break; |
@@ -601,6 +611,17 @@ Boolean LLFilePicker::navOpenFilterProc(AEDesc *theItem, void *info, void *callB | |||
601 | AEDisposeDesc(&desc); | 611 | AEDisposeDesc(&desc); |
602 | } | 612 | } |
603 | } | 613 | } |
614 | else if(filter == FFLOAD_APP) | ||
615 | { | ||
616 | // App bundles are of type APPL; ???? is a folder, and 0 is something going wrong. | ||
617 | if((int)navInfo->fileAndFolder.folderInfo.folderType != FOUR_CHAR_CODE('APPL') && | ||
618 | (int)navInfo->fileAndFolder.folderInfo.folderType != FOUR_CHAR_CODE('\?\?\?\?') && | ||
619 | (int)navInfo->fileAndFolder.folderInfo.folderType != 0 | ||
620 | ) | ||
621 | { | ||
622 | result = false; | ||
623 | } | ||
624 | } | ||
604 | } | 625 | } |
605 | return result; | 626 | return result; |
606 | } | 627 | } |
@@ -844,6 +865,9 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter) | |||
844 | reset(); | 865 | reset(); |
845 | 866 | ||
846 | mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; | 867 | mNavOptions.optionFlags &= ~kNavAllowMultipleFiles; |
868 | if(filter == FFLOAD_APP) | ||
869 | mNavOptions.optionFlags |= kNavSupportPackages; | ||
870 | |||
847 | // Modal, so pause agent | 871 | // Modal, so pause agent |
848 | send_agent_pause(); | 872 | send_agent_pause(); |
849 | { | 873 | { |
diff --git a/linden/indra/newview/llfilepicker.h b/linden/indra/newview/llfilepicker.h index fb20ed3..3925ae7 100644 --- a/linden/indra/newview/llfilepicker.h +++ b/linden/indra/newview/llfilepicker.h | |||
@@ -92,6 +92,7 @@ public: | |||
92 | FFLOAD_SLOBJECT = 7, | 92 | FFLOAD_SLOBJECT = 7, |
93 | FFLOAD_RAW = 8, | 93 | FFLOAD_RAW = 8, |
94 | FFLOAD_TEXT = 9, | 94 | FFLOAD_TEXT = 9, |
95 | FFLOAD_APP = 10 | ||
95 | }; | 96 | }; |
96 | 97 | ||
97 | enum ESaveFilter | 98 | enum ESaveFilter |
diff --git a/linden/indra/newview/llpreviewscript.cpp b/linden/indra/newview/llpreviewscript.cpp index d2d9ed5..a1c05c7 100644 --- a/linden/indra/newview/llpreviewscript.cpp +++ b/linden/indra/newview/llpreviewscript.cpp | |||
@@ -178,7 +178,11 @@ LLScriptEdCore::LLScriptEdCore( | |||
178 | mLastHelpToken(NULL), | 178 | mLastHelpToken(NULL), |
179 | mLiveHelpHistorySize(0), | 179 | mLiveHelpHistorySize(0), |
180 | mEnableSave(FALSE), | 180 | mEnableSave(FALSE), |
181 | mHasScriptData(FALSE) | 181 | mEnableXEd(FALSE), |
182 | mHasScriptData(FALSE), | ||
183 | // We need to check for a new file every five seconds, or autosave every 60. | ||
184 | // There's probably a better solution to both of the above. | ||
185 | LLEventTimer((gSavedSettings.getString("LSLExternalEditor").length() < 3) ? 60 : 5) | ||
182 | { | 186 | { |
183 | setFollowsAll(); | 187 | setFollowsAll(); |
184 | setBorderVisible(FALSE); | 188 | setBorderVisible(FALSE); |
@@ -209,11 +213,30 @@ LLScriptEdCore::LLScriptEdCore( | |||
209 | tooltips.push_back(ll_safe_string(gScriptLibrary.mFunctions[i]->mDesc)); | 213 | tooltips.push_back(ll_safe_string(gScriptLibrary.mFunctions[i]->mDesc)); |
210 | } | 214 | } |
211 | } | 215 | } |
216 | |||
217 | //gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"keywords.ini") | ||
218 | std::string keyword_path = gDirUtilp->getUserSkinDir() + gDirUtilp->getDirDelimiter() + "keywords.ini"; | ||
219 | if(!LLFile::isfile(keyword_path)) | ||
220 | { | ||
221 | llinfos << "nothing at " << keyword_path << llendl; | ||
222 | keyword_path = gDirUtilp->getSkinDir() + gDirUtilp->getDirDelimiter() + "keywords.ini"; | ||
223 | if(!LLFile::isfile(keyword_path)) | ||
224 | { | ||
225 | llinfos << "nothing at " << keyword_path << " ; will use default" << llendl; | ||
226 | keyword_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "keywords.ini"); | ||
227 | } | ||
228 | else | ||
229 | { | ||
230 | llinfos << "loaded skin-specific keywords from " << keyword_path << llendl; | ||
231 | } | ||
232 | } | ||
233 | else | ||
234 | { | ||
235 | llinfos << "loaded skin-specific keywords from " << keyword_path << llendl; | ||
236 | } | ||
212 | LLColor3 color(0.5f, 0.0f, 0.15f); | 237 | LLColor3 color(0.5f, 0.0f, 0.15f); |
213 | 238 | mEditor->loadKeywords(keyword_path, funcs, tooltips, color); | |
214 | mEditor->loadKeywords(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"keywords.ini"), funcs, tooltips, color); | ||
215 | 239 | ||
216 | |||
217 | LLKeywordToken *token; | 240 | LLKeywordToken *token; |
218 | LLKeywords::keyword_iterator_t token_it; | 241 | LLKeywords::keyword_iterator_t token_it; |
219 | for (token_it = mEditor->keywordsBegin(); token_it != mEditor->keywordsEnd(); ++token_it) | 242 | for (token_it = mEditor->keywordsBegin(); token_it != mEditor->keywordsEnd(); ++token_it) |
@@ -233,7 +256,6 @@ LLScriptEdCore::LLScriptEdCore( | |||
233 | 256 | ||
234 | childSetCommitCallback("lsl errors", &LLScriptEdCore::onErrorList, this); | 257 | childSetCommitCallback("lsl errors", &LLScriptEdCore::onErrorList, this); |
235 | childSetAction("Save_btn", onBtnSave,this); | 258 | childSetAction("Save_btn", onBtnSave,this); |
236 | |||
237 | initMenu(); | 259 | initMenu(); |
238 | 260 | ||
239 | // Do the work that addTabPanel() normally does. | 261 | // Do the work that addTabPanel() normally does. |
@@ -250,6 +272,23 @@ LLScriptEdCore::~LLScriptEdCore() | |||
250 | deleteBridges(); | 272 | deleteBridges(); |
251 | } | 273 | } |
252 | 274 | ||
275 | BOOL LLScriptEdCore::tick() | ||
276 | { | ||
277 | //autoSave(); | ||
278 | if (gSavedSettings.getString("LSLExternalEditor").length() < 3) | ||
279 | { | ||
280 | if (hasChanged(this)) | ||
281 | { | ||
282 | autoSave(); | ||
283 | } | ||
284 | } | ||
285 | else | ||
286 | { | ||
287 | XedUpd(); | ||
288 | } | ||
289 | return FALSE; | ||
290 | } | ||
291 | |||
253 | void LLScriptEdCore::initMenu() | 292 | void LLScriptEdCore::initMenu() |
254 | { | 293 | { |
255 | 294 | ||
@@ -297,6 +336,14 @@ void LLScriptEdCore::initMenu() | |||
297 | menuItem->setMenuCallback(onBtnHelp, this); | 336 | menuItem->setMenuCallback(onBtnHelp, this); |
298 | menuItem->setEnabledCallback(NULL); | 337 | menuItem->setEnabledCallback(NULL); |
299 | 338 | ||
339 | menuItem = getChild<LLMenuItemCallGL>("Set External Editor..."); | ||
340 | menuItem->setMenuCallback(onSetExternalEditor, this); | ||
341 | menuItem->setEnabledCallback(NULL); | ||
342 | |||
343 | menuItem = getChild<LLMenuItemCallGL>("Open in External Editor"); | ||
344 | menuItem->setMenuCallback(onBtnXEd, this); | ||
345 | menuItem->setEnabledCallback(enableExternalEditor); | ||
346 | |||
300 | menuItem = getChild<LLMenuItemCallGL>("Import Script..."); | 347 | menuItem = getChild<LLMenuItemCallGL>("Import Script..."); |
301 | menuItem->setMenuCallback(onBtnLoadFromDisc, this); | 348 | menuItem->setMenuCallback(onBtnLoadFromDisc, this); |
302 | menuItem->setEnabledCallback(NULL); | 349 | menuItem->setEnabledCallback(NULL); |
@@ -318,7 +365,9 @@ void LLScriptEdCore::setScriptText(const std::string& text, BOOL is_valid) | |||
318 | { | 365 | { |
319 | if (mEditor) | 366 | if (mEditor) |
320 | { | 367 | { |
321 | mEditor->setText(text); | 368 | std::string new_text(text); |
369 | LLStringUtil::replaceTabsWithSpaces(new_text, 4); // fix tabs in text | ||
370 | mEditor->setText(new_text); | ||
322 | mHasScriptData = is_valid; | 371 | mHasScriptData = is_valid; |
323 | } | 372 | } |
324 | } | 373 | } |
@@ -416,6 +465,175 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) | |||
416 | setHelpPage(LLStringUtil::null); | 465 | setHelpPage(LLStringUtil::null); |
417 | } | 466 | } |
418 | } | 467 | } |
468 | //dim | ||
469 | void LLScriptEdCore::xedLaunch() | ||
470 | { | ||
471 | //llinfos << "LLScriptEdCore::autoSave()" << llendl; | ||
472 | |||
473 | std::string editor = gSavedSettings.getString("LSLExternalEditor"); | ||
474 | if (!gDirUtilp->fileExists(editor)) | ||
475 | { | ||
476 | llwarns << "External editor " + editor + " not found" << llendl; | ||
477 | |||
478 | LLSD row; | ||
479 | row["columns"][0]["value"] = "Couldn't open external editor '" + editor + "'. File not found."; | ||
480 | row["columns"][0]["font"] = "SANSSERIF_SMALL"; | ||
481 | mErrorList->addElement(row); | ||
482 | return; | ||
483 | } | ||
484 | |||
485 | //std::string filepath = gDirUtilp->getExpandedFilename(gDirUtilp->getTempDir(),asset_id.asString()); | ||
486 | if( mXfname.empty() ) | ||
487 | { | ||
488 | std::string asfilename = gDirUtilp->getTempFilename(); | ||
489 | asfilename.replace( asfilename.length()-4, 12, "_Xed.lsl" ); | ||
490 | mXfname = asfilename; | ||
491 | //mAutosaveFilename = llformat("%s.lsl", asfilename.c_str()); | ||
492 | } | ||
493 | |||
494 | FILE* fp = LLFile::fopen(mXfname.c_str(), "wb"); | ||
495 | if(!fp) | ||
496 | { | ||
497 | llwarns << "Unable to write to " << mXfname << llendl; | ||
498 | |||
499 | LLSD row; | ||
500 | row["columns"][0]["value"] = "Error writing to temp file. Is your hard drive full?"; | ||
501 | row["columns"][0]["font"] = "SANSSERIF_SMALL"; | ||
502 | mErrorList->addElement(row); | ||
503 | return; | ||
504 | } | ||
505 | mEditor->setEnabled(FALSE); | ||
506 | std::string utf8text = mEditor->getText(); | ||
507 | fputs(utf8text.c_str(), fp); | ||
508 | fclose(fp); | ||
509 | fp = NULL; | ||
510 | llinfos << "XEditor: " << mXfname << llendl; | ||
511 | //record the stat | ||
512 | stat(mXfname.c_str(), &mXstbuf); | ||
513 | //launch | ||
514 | #if LL_WINDOWS | ||
515 | //just to get rid of the pesky black window | ||
516 | std::string exe = gSavedSettings.getString("LSLExternalEditor"); | ||
517 | S32 spaces=0; | ||
518 | for(S32 i=0; i!=exe.size(); ++i) | ||
519 | { | ||
520 | spaces+=( exe.at(i)==' '); | ||
521 | } | ||
522 | if(spaces > 0) | ||
523 | { | ||
524 | exe = "\""+exe+"\""; | ||
525 | } | ||
526 | std::string theCMD("%COMSPEC% /c START \"External Editor\" " + exe + " " + mXfname + " & exit"); | ||
527 | llinfos << "FINAL COMMAND IS :"<< | ||
528 | theCMD.c_str() << llendl; | ||
529 | |||
530 | std::system(theCMD.c_str()); | ||
531 | #elif LL_DARWIN | ||
532 | // Use Launch Services for this - launching another instance is fail (and incorrect on OS X) | ||
533 | CFStringRef strPath = CFStringCreateWithCString(kCFAllocatorDefault, mXfname.c_str(), kCFStringEncodingUTF8); | ||
534 | CFURLRef tempPath = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, strPath, kCFURLPOSIXPathStyle, false); | ||
535 | CFURLRef tempPathArray[1] = { tempPath }; | ||
536 | CFArrayRef arguments = CFArrayCreate(kCFAllocatorDefault, (const void **)tempPathArray, 1, NULL); | ||
537 | LSApplicationParameters appParams; | ||
538 | memset(&appParams, 0, sizeof(appParams)); | ||
539 | FSRef ref; | ||
540 | FSPathMakeRef((UInt8*)gSavedSettings.getString("LSLExternalEditor").c_str(), &ref, NULL); | ||
541 | appParams.application = &ref; | ||
542 | appParams.flags = kLSLaunchAsync | kLSLaunchStartClassic; | ||
543 | LSOpenURLsWithRole(arguments, kLSRolesAll, NULL, &appParams, NULL, 0); | ||
544 | CFRelease(arguments); | ||
545 | CFRelease(tempPath); | ||
546 | CFRelease(strPath); | ||
547 | #else | ||
548 | //std::system(std::string(gSavedSettings.getString("LSLExternalEditor") + " " + mXfname).c_str()); | ||
549 | |||
550 | // Any approach involving std::system will fail because SL eats signals. | ||
551 | // This was stolen from floaterskinfinder.cpp. | ||
552 | std::string exe = gSavedSettings.getString("LSLExternalEditor"); | ||
553 | const char *zargv[] = {exe.c_str(), mXfname.c_str(), NULL}; | ||
554 | fflush(NULL); | ||
555 | pid_t id = vfork(); | ||
556 | if(id == 0) | ||
557 | { | ||
558 | execv(exe.c_str(), (char **)zargv); | ||
559 | _exit(0); // This shouldn't ever be reached. | ||
560 | } | ||
561 | #endif | ||
562 | } | ||
563 | |||
564 | void LLScriptEdCore::XedUpd() | ||
565 | { | ||
566 | struct stat stbuf; | ||
567 | stat(this->mXfname.c_str() , &stbuf); | ||
568 | if (this->mXstbuf.st_mtime != stbuf.st_mtime) | ||
569 | { | ||
570 | this->mErrorList->addCommentText(std::string("Change Detected... Updating")); | ||
571 | |||
572 | this->mXstbuf = stbuf; | ||
573 | LLFILE* file = LLFile::fopen(this->mXfname, "rb"); /*Flawfinder: ignore*/ | ||
574 | if(file) | ||
575 | { | ||
576 | // read in the whole file | ||
577 | fseek(file, 0L, SEEK_END); | ||
578 | S64 file_length = ftell(file); | ||
579 | fseek(file, 0L, SEEK_SET); | ||
580 | char* buffer = new char[file_length+1]; | ||
581 | size_t nread = fread(buffer, 1, file_length, file); | ||
582 | if (nread < (size_t) file_length) | ||
583 | { | ||
584 | llwarns << "Short read" << llendl; | ||
585 | } | ||
586 | buffer[nread] = '\0'; | ||
587 | fclose(file); | ||
588 | std::string ttext = LLStringExplicit(buffer); | ||
589 | LLStringUtil::replaceTabsWithSpaces(ttext, 4); | ||
590 | mEditor->setText(ttext); | ||
591 | LLScriptEdCore::doSave( this, FALSE ); | ||
592 | //mEditor->makePristine(); | ||
593 | delete[] buffer; | ||
594 | buffer = NULL; | ||
595 | } | ||
596 | else | ||
597 | { | ||
598 | llwarns << "Error opening " << this->mXfname << llendl; | ||
599 | } | ||
600 | } | ||
601 | } | ||
602 | //end dim | ||
603 | void LLScriptEdCore::autoSave() | ||
604 | { | ||
605 | //llinfos << "LLScriptEdCore::autoSave()" << llendl; | ||
606 | if(mEditor->isPristine()) | ||
607 | { | ||
608 | return; | ||
609 | } | ||
610 | //std::string filepath = gDirUtilp->getExpandedFilename(gDirUtilp->getTempDir(),asset_id.asString()); | ||
611 | if( mAutosaveFilename.empty() ) | ||
612 | { | ||
613 | std::string asfilename = gDirUtilp->getTempFilename(); | ||
614 | asfilename.replace( asfilename.length()-4, 12, "_autosave.lsl" ); | ||
615 | mAutosaveFilename = asfilename; | ||
616 | //mAutosaveFilename = llformat("%s.lsl", asfilename.c_str()); | ||
617 | } | ||
618 | |||
619 | FILE* fp = LLFile::fopen(mAutosaveFilename.c_str(), "wb"); | ||
620 | if(!fp) | ||
621 | { | ||
622 | llwarns << "Unable to write to " << mAutosaveFilename << llendl; | ||
623 | |||
624 | LLSD row; | ||
625 | row["columns"][0]["value"] = "Error writing to temp file. Is your hard drive full?"; | ||
626 | row["columns"][0]["font"] = "SANSSERIF_SMALL"; | ||
627 | mErrorList->addElement(row); | ||
628 | return; | ||
629 | } | ||
630 | |||
631 | std::string utf8text = mEditor->getText(); | ||
632 | fputs(utf8text.c_str(), fp); | ||
633 | fclose(fp); | ||
634 | fp = NULL; | ||
635 | llinfos << "autosave: " << mAutosaveFilename << llendl; | ||
636 | } | ||
419 | 637 | ||
420 | void LLScriptEdCore::setHelpPage(const std::string& help_string) | 638 | void LLScriptEdCore::setHelpPage(const std::string& help_string) |
421 | { | 639 | { |
@@ -507,6 +725,11 @@ bool LLScriptEdCore::handleSaveChangesDialog(const LLSD& notification, const LLS | |||
507 | break; | 725 | break; |
508 | 726 | ||
509 | case 1: // "No" | 727 | case 1: // "No" |
728 | if( !mXfname.empty()) | ||
729 | { | ||
730 | llinfos << "remove autosave: " << mXfname << llendl; | ||
731 | LLFile::remove(mXfname.c_str()); | ||
732 | } | ||
510 | mForceClose = TRUE; | 733 | mForceClose = TRUE; |
511 | // This will close immediately because mForceClose is true, so we won't | 734 | // This will close immediately because mForceClose is true, so we won't |
512 | // infinite loop with these dialogs. JC | 735 | // infinite loop with these dialogs. JC |
@@ -724,6 +947,34 @@ void LLScriptEdCore::onBtnSave(void* data) | |||
724 | } | 947 | } |
725 | 948 | ||
726 | // static | 949 | // static |
950 | void LLScriptEdCore::onSetExternalEditor(void* data) | ||
951 | { | ||
952 | std::string cur_name(gSavedSettings.getString("LSLExternalEditor")); | ||
953 | |||
954 | LLFilePicker& picker = LLFilePicker::instance(); | ||
955 | if (! picker.getOpenFile(LLFilePicker::FFLOAD_APP) ) | ||
956 | { | ||
957 | return; //Canceled! | ||
958 | } | ||
959 | std::string file_name = picker.getFirstFile(); | ||
960 | if (!file_name.empty() && file_name != cur_name) | ||
961 | { | ||
962 | gSavedSettings.setString("LSLExternalEditor", file_name); | ||
963 | } | ||
964 | else | ||
965 | { | ||
966 | gSavedSettings.setString("LSLExternalEditor", ""); | ||
967 | } | ||
968 | } | ||
969 | |||
970 | //static | ||
971 | void LLScriptEdCore::onBtnXEd(void* data) | ||
972 | { | ||
973 | LLScriptEdCore* self = (LLScriptEdCore*)data; | ||
974 | self->xedLaunch(); | ||
975 | } | ||
976 | |||
977 | // static | ||
727 | void LLScriptEdCore::onBtnUndoChanges( void* userdata ) | 978 | void LLScriptEdCore::onBtnUndoChanges( void* userdata ) |
728 | { | 979 | { |
729 | LLScriptEdCore* self = (LLScriptEdCore*) userdata; | 980 | LLScriptEdCore* self = (LLScriptEdCore*) userdata; |
@@ -904,6 +1155,12 @@ BOOL LLScriptEdCore::enableDeselectMenu(void* userdata) | |||
904 | } | 1155 | } |
905 | 1156 | ||
906 | // static | 1157 | // static |
1158 | BOOL LLScriptEdCore::enableExternalEditor(void* userdata) | ||
1159 | { | ||
1160 | return (gSavedSettings.getString("LSLExternalEditor").length() > 3); | ||
1161 | } | ||
1162 | |||
1163 | // static | ||
907 | void LLScriptEdCore::onErrorList(LLUICtrl*, void* user_data) | 1164 | void LLScriptEdCore::onErrorList(LLUICtrl*, void* user_data) |
908 | { | 1165 | { |
909 | LLScriptEdCore* self = (LLScriptEdCore*)user_data; | 1166 | LLScriptEdCore* self = (LLScriptEdCore*)user_data; |
@@ -989,6 +1246,11 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask) | |||
989 | if(mSaveCallback) | 1246 | if(mSaveCallback) |
990 | { | 1247 | { |
991 | // don't close after saving | 1248 | // don't close after saving |
1249 | if (!hasChanged(this)) | ||
1250 | { | ||
1251 | llinfos << "Save Not Needed" << llendl; | ||
1252 | return TRUE; | ||
1253 | } | ||
992 | mSaveCallback(mUserdata, FALSE); | 1254 | mSaveCallback(mUserdata, FALSE); |
993 | } | 1255 | } |
994 | 1256 | ||
@@ -1181,6 +1443,11 @@ void LLPreviewLSL::closeIfNeeded() | |||
1181 | mPendingUploads--; | 1443 | mPendingUploads--; |
1182 | if (mPendingUploads <= 0 && mCloseAfterSave) | 1444 | if (mPendingUploads <= 0 && mCloseAfterSave) |
1183 | { | 1445 | { |
1446 | if( !mScriptEd->mXfname.empty()) | ||
1447 | { | ||
1448 | llinfos << "remove autosave: " << mScriptEd->mXfname << llendl; | ||
1449 | LLFile::remove(mScriptEd->mXfname.c_str()); | ||
1450 | } | ||
1184 | close(); | 1451 | close(); |
1185 | } | 1452 | } |
1186 | } | 1453 | } |
@@ -2349,6 +2616,11 @@ void LLLiveLSLEditor::closeIfNeeded() | |||
2349 | mPendingUploads--; | 2616 | mPendingUploads--; |
2350 | if (mPendingUploads <= 0 && mCloseAfterSave) | 2617 | if (mPendingUploads <= 0 && mCloseAfterSave) |
2351 | { | 2618 | { |
2619 | if( !mScriptEd->mXfname.empty()) | ||
2620 | { | ||
2621 | llinfos << "remove autosave: " << mScriptEd->mXfname << llendl; | ||
2622 | LLFile::remove(mScriptEd->mXfname.c_str()); | ||
2623 | } | ||
2352 | close(); | 2624 | close(); |
2353 | } | 2625 | } |
2354 | } | 2626 | } |
diff --git a/linden/indra/newview/llpreviewscript.h b/linden/indra/newview/llpreviewscript.h index 8e61435..4de886e 100644 --- a/linden/indra/newview/llpreviewscript.h +++ b/linden/indra/newview/llpreviewscript.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #include "llcombobox.h" | 40 | #include "llcombobox.h" |
41 | #include "lliconctrl.h" | 41 | #include "lliconctrl.h" |
42 | #include "llframetimer.h" | 42 | #include "llframetimer.h" |
43 | #include "lltimer.h" | ||
43 | 44 | ||
44 | 45 | ||
45 | class LLMessageSystem; | 46 | class LLMessageSystem; |
@@ -53,7 +54,7 @@ class LLMenuBarGL; | |||
53 | class LLKeywordToken; | 54 | class LLKeywordToken; |
54 | 55 | ||
55 | // Inner, implementation class. LLPreviewScript and LLLiveLSLEditor each own one of these. | 56 | // Inner, implementation class. LLPreviewScript and LLLiveLSLEditor each own one of these. |
56 | class LLScriptEdCore : public LLPanel | 57 | class LLScriptEdCore : public LLPanel, public LLEventTimer |
57 | { | 58 | { |
58 | friend class LLPreviewScript; | 59 | friend class LLPreviewScript; |
59 | friend class LLPreviewLSL; | 60 | friend class LLPreviewLSL; |
@@ -96,6 +97,8 @@ public: | |||
96 | static void onBtnInsertFunction(LLUICtrl*, void*); | 97 | static void onBtnInsertFunction(LLUICtrl*, void*); |
97 | static void doSave( void* userdata, BOOL close_after_save ); | 98 | static void doSave( void* userdata, BOOL close_after_save ); |
98 | static void onBtnSave(void*); | 99 | static void onBtnSave(void*); |
100 | static void onSetExternalEditor(void* data); | ||
101 | static void onBtnXEd(void*); | ||
99 | static void onBtnUndoChanges(void*); | 102 | static void onBtnUndoChanges(void*); |
100 | static void onBtnSaveToDisc(void*); | 103 | static void onBtnSaveToDisc(void*); |
101 | static void onBtnLoadFromDisc(void*); | 104 | static void onBtnLoadFromDisc(void*); |
@@ -117,13 +120,21 @@ public: | |||
117 | static BOOL enablePasteMenu(void* userdata); | 120 | static BOOL enablePasteMenu(void* userdata); |
118 | static BOOL enableSelectAllMenu(void* userdata); | 121 | static BOOL enableSelectAllMenu(void* userdata); |
119 | static BOOL enableDeselectMenu(void* userdata); | 122 | static BOOL enableDeselectMenu(void* userdata); |
123 | static BOOL enableExternalEditor(void* userdata); | ||
120 | 124 | ||
121 | static BOOL hasChanged(void* userdata); | 125 | static BOOL hasChanged(void* userdata); |
122 | 126 | ||
123 | void selectFirstError(); | 127 | void selectFirstError(); |
128 | |||
129 | void autoSave(); | ||
130 | //dim external ed | ||
131 | void XedUpd(); | ||
132 | void xedLaunch(); | ||
124 | 133 | ||
125 | virtual BOOL handleKeyHere(KEY key, MASK mask); | 134 | virtual BOOL handleKeyHere(KEY key, MASK mask); |
126 | 135 | ||
136 | virtual BOOL tick(); | ||
137 | |||
127 | void enableSave(BOOL b) {mEnableSave = b;} | 138 | void enableSave(BOOL b) {mEnableSave = b;} |
128 | 139 | ||
129 | protected: | 140 | protected: |
@@ -137,6 +148,9 @@ protected: | |||
137 | 148 | ||
138 | private: | 149 | private: |
139 | std::string mSampleText; | 150 | std::string mSampleText; |
151 | std::string mAutosaveFilename; | ||
152 | std::string mXfname; | ||
153 | struct stat mXstbuf; | ||
140 | std::string mHelpURL; | 154 | std::string mHelpURL; |
141 | std::string mScriptTitle; | 155 | std::string mScriptTitle; |
142 | LLTextEditor* mEditor; | 156 | LLTextEditor* mEditor; |
@@ -155,6 +169,7 @@ private: | |||
155 | LLFrameTimer mLiveHelpTimer; | 169 | LLFrameTimer mLiveHelpTimer; |
156 | S32 mLiveHelpHistorySize; | 170 | S32 mLiveHelpHistorySize; |
157 | BOOL mEnableSave; | 171 | BOOL mEnableSave; |
172 | BOOL mEnableXEd; | ||
158 | BOOL mHasScriptData; | 173 | BOOL mHasScriptData; |
159 | }; | 174 | }; |
160 | 175 | ||
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_live_lsleditor.xml b/linden/indra/newview/skins/default/xui/en-us/floater_live_lsleditor.xml index 2e91a82..9dda4ec 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_live_lsleditor.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_live_lsleditor.xml | |||
@@ -4,7 +4,7 @@ | |||
4 | min_height="271" min_width="290" mouse_opaque="true" name="script ed float" | 4 | min_height="271" min_width="290" mouse_opaque="true" name="script ed float" |
5 | rect_control="FloaterOpenObjectRect" title="Script: New Script" width="500" border_drop_shadow_visible="false" border_visible="false" bevel_style="none" border_style="line" border_thickness="0"> | 5 | rect_control="FloaterOpenObjectRect" title="Script: New Script" width="500" border_drop_shadow_visible="false" border_visible="false" bevel_style="none" border_style="line" border_thickness="0"> |
6 | <button bottom="-545" enabled="true" follows="right|bottom" font="SansSerif" | 6 | <button bottom="-545" enabled="true" follows="right|bottom" font="SansSerif" |
7 | halign="center" height="20" label="Reset" label_selected="Reset" left="362" | 7 | halign="center" height="22" label="Reset" label_selected="Reset" left="360" |
8 | mouse_opaque="true" name="Reset" width="128" /> | 8 | mouse_opaque="true" name="Reset" width="128" /> |
9 | <check_box bottom="-545" enabled="false" follows="left|bottom" font="SansSerif" | 9 | <check_box bottom="-545" enabled="false" follows="left|bottom" font="SansSerif" |
10 | height="18" initial_value="true" label="Running" left="12" | 10 | height="18" initial_value="true" label="Running" left="12" |
diff --git a/linden/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml b/linden/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml index 0175508..4e13090 100644 --- a/linden/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml +++ b/linden/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml | |||
@@ -9,7 +9,7 @@ | |||
9 | Loading... | 9 | Loading... |
10 | </text_editor> | 10 | </text_editor> |
11 | <button bottom="-499" enabled="true" follows="right|bottom" font="SansSerif" | 11 | <button bottom="-499" enabled="true" follows="right|bottom" font="SansSerif" |
12 | halign="center" height="20" label="Save" label_selected="Save" left="360" | 12 | halign="center" height="22" label="Save" label_selected="Save" left="360" |
13 | mouse_opaque="true" name="Save_btn" width="128" /> | 13 | mouse_opaque="true" name="Save_btn" width="128" /> |
14 | <scroll_list background_visible="true" bottom="-457" column_padding="5" draw_border="true" | 14 | <scroll_list background_visible="true" bottom="-457" column_padding="5" draw_border="true" |
15 | draw_heading="false" draw_stripes="true" enabled="true" | 15 | draw_heading="false" draw_stripes="true" enabled="true" |
@@ -36,11 +36,17 @@ | |||
36 | <menu_item_call bottom_delta="-58" height="20" label="Revert All Changes" left="0" | 36 | <menu_item_call bottom_delta="-58" height="20" label="Revert All Changes" left="0" |
37 | mouse_opaque="true" name="Revert All Changes" width="138" /> | 37 | mouse_opaque="true" name="Revert All Changes" width="138" /> |
38 | <menu_item_separator bottom_delta="-66" height="8" left="0" mouse_opaque="true" name="separator" | 38 | <menu_item_separator bottom_delta="-66" height="8" left="0" mouse_opaque="true" name="separator" |
39 | width="138" /> | 39 | width="138" /> |
40 | <menu_item_call bottom_delta="-76" height="20" label="Set External Editor..." left="0" | ||
41 | mouse_opaque="true" name="Set External Editor..." width="138" /> | ||
42 | <menu_item_call bottom_delta="-96" height="20" label="Open in External Editor" left="0" | ||
43 | mouse_opaque="true" name="Open in External Editor" width="138" /> | ||
44 | <menu_item_separator bottom_delta="-66" height="8" left="0" mouse_opaque="true" name="separator2" | ||
45 | width="138" /> | ||
40 | <menu_item_call bottom_delta="-76" height="20" label="Export Script..." left="0" | 46 | <menu_item_call bottom_delta="-76" height="20" label="Export Script..." left="0" |
41 | mouse_opaque="true" name="Export Script..." width="138" /> | 47 | mouse_opaque="true" name="Export Script..." width="138" /> |
42 | <menu_item_call bottom_delta="-96" height="20" label="Import Script..." left="0" | 48 | <menu_item_call bottom_delta="-96" height="20" label="Import Script..." left="0" |
43 | mouse_opaque="true" name="Import Script..." width="138" /> | 49 | mouse_opaque="true" name="Import Script..." width="138" /> |
44 | </menu> | 50 | </menu> |
45 | <menu bottom="665" drop_shadow="true" enabled="true" height="198" | 51 | <menu bottom="665" drop_shadow="true" enabled="true" height="198" |
46 | left="222" mouse_opaque="false" name="Edit" opaque="true" tear_off="false" | 52 | left="222" mouse_opaque="false" name="Edit" opaque="true" tear_off="false" |