From d0c18bc54c926f381c74a9cc68edaecca7ace9cc Mon Sep 17 00:00:00 2001 From: Inusaito Sayori Date: Wed, 31 Jul 2013 02:20:55 -0400 Subject: [PATCH] Modernize LLPreviewScript Should fix Fritigern's recent issues, seems to. (Mainly, the double clicking on script errors not working right thing) Should also fix that issue someone has brought up in group chat about the delay in our external editor sync in comparison to V3 --- indra/newview/llassetuploadresponders.cpp | 2 +- indra/newview/llpanelobjectinventory.cpp | 4 +- indra/newview/llpreviewscript.cpp | 818 +++++++--------------- indra/newview/llpreviewscript.h | 142 ++-- 4 files changed, 341 insertions(+), 625 deletions(-) diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp index de8da30e6..004152f46 100644 --- a/indra/newview/llassetuploadresponders.cpp +++ b/indra/newview/llassetuploadresponders.cpp @@ -683,7 +683,7 @@ void LLUpdateTaskInventoryResponder::uploadComplete(const LLSD& content) } else { - LLLiveLSLEditor* preview = LLLiveLSLEditor::find(item_id, task_id); + LLLiveLSLEditor* preview = static_cast(LLPreview::find(item_id)); if (preview) { // Bytecode save completed diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 380607cd4..e9f46c0b4 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -1250,7 +1250,7 @@ public: void LLTaskLSLBridge::openItem() { llinfos << "LLTaskLSLBridge::openItem() " << mUUID << llendl; - if(LLLiveLSLEditor::show(mUUID, mPanel->getTaskUUID())) + if(LLLiveLSLEditor::show(mUUID)) { return; } @@ -1299,7 +1299,7 @@ void LLTaskLSLBridge::openItem() BOOL LLTaskLSLBridge::removeItem() { - LLLiveLSLEditor::hide(mUUID, mPanel->getTaskUUID()); + LLLiveLSLEditor::hide(mUUID); return LLTaskInvFVBridge::removeItem(); } diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp index c9f1adffc..2f02bcd00 100644 --- a/indra/newview/llpreviewscript.cpp +++ b/indra/newview/llpreviewscript.cpp @@ -123,7 +123,6 @@ const S32 SCRIPT_PAD = 5; const S32 SCRIPT_BUTTON_WIDTH = 128; const S32 SCRIPT_BUTTON_HEIGHT = 24; // HACK: Use BTN_HEIGHT where possible. const S32 LINE_COLUMN_HEIGHT = 14; -const S32 BTN_PAD = 8; const S32 SCRIPT_EDITOR_MIN_HEIGHT = 2 * SCROLLBAR_SIZE + 2 * LLPANEL_BORDER_WIDTH + 128; @@ -141,7 +140,6 @@ const S32 SCRIPT_MIN_HEIGHT = const S32 MAX_EXPORT_SIZE = 1000; -const S32 TEXT_EDIT_COLUMN_HEIGHT = 16; const S32 MAX_HISTORY_COUNT = 10; const F32 LIVE_HELP_REFRESH_TIME = 1.f; @@ -236,22 +234,17 @@ void LLScriptEdCore::parseFunctions(const std::string& filename) } LLScriptEdCore::LLScriptEdCore( - const std::string& name, - const LLRect& rect, + LLScriptEdContainer* container, const std::string& sample, - const std::string& help_url, const LLHandle& floater_handle, void (*load_callback)(void*), void (*save_callback)(void*, BOOL), void (*search_replace_callback) (void* userdata), void* userdata, - LLUUID objectUUID, - LLUUID itemUUID, S32 bottom_pad) : - LLPanel( std::string("name"), rect ), + LLPanel(), mSampleText(sample), - mHelpURL(help_url), mEditor( NULL ), mLoadCallback( load_callback ), mSaveCallback( save_callback ), @@ -262,17 +255,25 @@ LLScriptEdCore::LLScriptEdCore( mLiveHelpHistorySize(0), mEnableSave(FALSE), mLiveFile(NULL), - mHasScriptData(FALSE), - LLEventTimer(60), - mObjectUUID(objectUUID), - mItemUUID(itemUUID) + mContainer(container), + mHasScriptData(FALSE) { setFollowsAll(); setBorderVisible(FALSE); - LLUICtrlFactory::getInstance()->buildPanel(this, "floater_script_ed_panel.xml"); + llassert_always(mContainer != NULL); +} +LLScriptEdCore::~LLScriptEdCore() +{ + deleteBridges(); + + delete mLiveFile; +} + +BOOL LLScriptEdCore::postBuild() +{ mErrorList = getChild("lsl errors"); mFunctions = getChild( "Insert..."); @@ -280,10 +281,14 @@ LLScriptEdCore::LLScriptEdCore( childSetCommitCallback("Insert...", &LLScriptEdCore::onBtnInsertFunction, this); mEditor = getChild("Script Editor"); - mEditor->setFollowsAll(); mEditor->setHandleEditKeysDirectly(TRUE); - mEditor->setEnabled(TRUE); - mEditor->setWordWrap(TRUE); + + childSetCommitCallback("lsl errors", &LLScriptEdCore::onErrorList, this); + childSetAction("Save_btn", boost::bind(&LLScriptEdCore::doSave,this,FALSE)); + childSetAction("Edit_btn", boost::bind(&LLScriptEdCore::openInExternalEditor, this)); + + initMenu(); + std::vector funcs; std::vector tooltips; @@ -359,38 +364,16 @@ LLScriptEdCore::LLScriptEdCore( { mFunctions->add(*iter); } - - childSetCommitCallback("lsl errors", &LLScriptEdCore::onErrorList, this); - childSetAction("Save_btn", onBtnSave,this); - childSetAction("Edit_btn", openInExternalEditor, this); - initMenu(); - - // Do the work that addTabPanel() normally does. - //LLRect tab_panel_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 ); - //tab_panel_rect.stretch( -LLPANEL_BORDER_WIDTH ); - //mCodePanel->setFollowsAll(); - //mCodePanel->translate( tab_panel_rect.mLeft - mCodePanel->getRect().mLeft, tab_panel_rect.mBottom - mCodePanel->getRect().mBottom); - //mCodePanel->reshape( tab_panel_rect.getWidth(), tab_panel_rect.getHeight(), TRUE ); - -} - -LLScriptEdCore::~LLScriptEdCore() -{ - deleteBridges(); - delete mLiveFile; -} - -BOOL LLScriptEdCore::tick() -{ - autoSave(); - return FALSE; + return TRUE; } void LLScriptEdCore::initMenu() { + // *TODO: Skinning - make these callbacks data driven + LLMenuItemCallGL* menuItem; - LLMenuItemCallGL* menuItem = getChild("Save"); + menuItem = getChild("Save"); menuItem->setMenuCallback(onBtnSave, this); menuItem->setEnabledCallback(hasChanged); @@ -489,7 +472,10 @@ bool LLScriptEdCore::writeToFile(const std::string& filename) { llwarns << "Unable to write to " << filename << llendl; - mErrorList->addSimpleElement(LLTrans::getString("CompileQueueProblemWriting")); + LLSD row; + row["columns"][0]["value"] = LLTrans::getString("CompileQueueProblemWriting"); + row["columns"][0]["font"] = "SANSSERIF_SMALL"; + mErrorList->addElement(row); return false; } @@ -509,7 +495,7 @@ bool LLScriptEdCore::writeToFile(const std::string& filename) void LLScriptEdCore::sync() { // Sync with external editor. - std::string tmp_file = getTmpFileName(); + std::string tmp_file = mContainer->getTmpFileName(); llstat s; if (LLFile::stat(tmp_file, &s) == 0) // file exists { @@ -518,45 +504,17 @@ void LLScriptEdCore::sync() } } -std::string LLScriptEdCore::getTmpFileName() +bool LLScriptEdCore::hasChanged() { - // Take script inventory item id (within the object inventory) - // to consideration so that it's possible to edit multiple scripts - // in the same object inventory simultaneously (STORM-781). - std::string script_id = mObjectUUID.asString() + "_" + mItemUUID.asString(); + if (!mEditor) return false; - // Use MD5 sum to make the file name shorter and not exceed maximum path length. - char script_id_hash_str[33]; /* Flawfinder: ignore */ - LLMD5 script_id_hash((const U8 *)script_id.c_str()); - script_id_hash.hex_digest(script_id_hash_str); - - return std::string(LLFile::tmpdir()) + "sl_script_" + script_id_hash_str + ".lsl"; -} - -bool LLScriptEdCore::onExternalChange(const std::string& filename) -{ - if (!loadScriptText(filename)) - { - return false; - } - - // Avoid recursive save/compile loop - doSave(this, false, false); - return true; -} - -BOOL LLScriptEdCore::hasChanged(void* userdata) -{ - LLScriptEdCore* self = (LLScriptEdCore*)userdata; - if (!self || !self->mEditor) return FALSE; - - return ((!self->mEditor->isPristine() || self->mEnableSave) && self->mHasScriptData); + return ((!mEditor->isPristine() || mEnableSave) && mHasScriptData); } void LLScriptEdCore::draw() { - BOOL script_changed = hasChanged(this); - childSetEnabled("Save_btn", script_changed); + BOOL script_changed = hasChanged(); + getChildView("Save_btn")->setEnabled(script_changed); if( mEditor->hasFocus() ) { @@ -565,11 +523,11 @@ void LLScriptEdCore::draw() mEditor->getCurrentLineAndColumn( &line, &column, FALSE ); // don't include wordwrap std::string cursor_pos; cursor_pos = llformat("Line %d, Column %d", line, column ); - childSetText("line_col", cursor_pos); + getChild("line_col")->setValue(cursor_pos); } else { - childSetText("line_col", LLStringUtil::null); + getChild("line_col")->setValue(LLStringUtil::null); } updateDynamicHelp(); @@ -633,43 +591,15 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate) mLiveHelpTimer.stop(); } } - else if (immediate) + else { - setHelpPage(LLStringUtil::null); + if (immediate) + { + setHelpPage(LLStringUtil::null); + } } } -void LLScriptEdCore::autoSave() -{ - //llinfos << "LLScriptEdCore::autoSave()" << llendl; - if(mEditor->isPristine()) - { - return; - } - //std::string filepath = gDirUtilp->getExpandedFilename(gDirUtilp->getTempDir(),asset_id.asString()); - if( mAutosaveFilename.empty() ) { - std::string asfilename = gDirUtilp->getTempFilename(); - asfilename.replace( asfilename.length()-4, 12, "_autosave.lsl" ); - mAutosaveFilename = asfilename; - //mAutosaveFilename = llformat("%s.lsl", asfilename.c_str()); - } - - LLFILE* fp = LLFile::fopen(mAutosaveFilename.c_str(), "wb"); - if(!fp) - { - llwarns << "Unable to write to " << mAutosaveFilename << llendl; - - mErrorList->addSimpleElement(LLTrans::getString("CompileQueueProblemWriting")); - return; - } - - std::string utf8text = mEditor->getText(); - fputs(utf8text.c_str(), fp); - fclose(fp); - fp = NULL; - llinfos << "autosave: " << mAutosaveFilename << llendl; -} - void LLScriptEdCore::setHelpPage(const std::string& help_string) { LLFloater* help_floater = mLiveHelpHandle.get(); @@ -682,6 +612,7 @@ void LLScriptEdCore::setHelpPage(const std::string& help_string) if (!history_combo) return; LLUIString url_string = gSavedSettings.getString("LSLHelpURL"); + url_string.setArg("[LSL_STRING]", help_string); addHelpItemToHistory(help_string); @@ -734,7 +665,7 @@ void LLScriptEdCore::addHelpItemToHistory(const std::string& help_string) BOOL LLScriptEdCore::canClose() { - if(mForceClose || !hasChanged(this)) + if(mForceClose || !hasChanged()) { return TRUE; } @@ -746,6 +677,12 @@ BOOL LLScriptEdCore::canClose() } } +void LLScriptEdCore::setEnableEditing(bool enable) +{ + mEditor->setEnabled(enable); + getChildView("Edit_btn")->setEnabled(enable); +} + bool LLScriptEdCore::handleSaveChangesDialog(const LLSD& notification, const LLSD& response ) { S32 option = LLNotificationsUtil::getSelectedOption(notification, response); @@ -753,15 +690,10 @@ bool LLScriptEdCore::handleSaveChangesDialog(const LLSD& notification, const LLS { case 0: // "Yes" // close after saving - LLScriptEdCore::doSave( this, TRUE ); + doSave( TRUE ); break; case 1: // "No" - if( !mAutosaveFilename.empty()) - { - llinfos << "remove autosave: " << mAutosaveFilename << llendl; - LLFile::remove(mAutosaveFilename.c_str()); - } mForceClose = TRUE; // This will close immediately because mForceClose is true, so we won't // infinite loop with these dialogs. JC @@ -796,9 +728,8 @@ bool LLScriptEdCore::onHelpWebDialog(const LLSD& notification, const LLSD& respo // static void LLScriptEdCore::onBtnHelp(void* userdata) { - LLScriptEdCore* corep = (LLScriptEdCore*)userdata; LLSD payload; - payload["help_url"] = corep->mHelpURL; + payload["help_url"] = HELP_LSL_URL; LLNotificationsUtil::add("WebLaunchLSLGuide", LLSD(), payload, onHelpWebDialog); } @@ -932,37 +863,27 @@ void LLScriptEdCore::onBtnInsertFunction(LLUICtrl *ui, void* userdata) self->setHelpPage(self->mFunctions->getSimple()); } -// static -void LLScriptEdCore::doSave( void* userdata, BOOL close_after_save, BOOL sync_external_editor) +void LLScriptEdCore::doSave( BOOL close_after_save) { LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT ); - LLScriptEdCore* self = (LLScriptEdCore*) userdata; - - if( self->mSaveCallback ) + if( mSaveCallback ) { - self->mSaveCallback( self->mUserdata, close_after_save ); - } - if ( sync_external_editor ) - { - self->sync(); + mSaveCallback( mUserdata, close_after_save ); } } -void LLScriptEdCore::openInExternalEditor(void *userdata) +void LLScriptEdCore::openInExternalEditor() { - LLScriptEdCore* self = (LLScriptEdCore*) userdata; - - delete self->mLiveFile; // deletes file + delete mLiveFile; // deletes file // Save the script to a temporary file. - std::string filename = self->getTmpFileName(); - self->writeToFile(filename); + std::string filename = mContainer->getTmpFileName(); + writeToFile(filename); // Start watching file changes. - self->mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLScriptEdCore::onExternalChange, self, _1)); - self->mLiveFile->ignoreNextUpdate(); - self->mLiveFile->addToEventTimer(); + mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLScriptEdContainer::onExternalChange, mContainer, _1)); + mLiveFile->addToEventTimer(); // Open it in external editor. { @@ -995,21 +916,32 @@ void LLScriptEdCore::openInExternalEditor(void *userdata) } } +void LLScriptEdCore::onBtnUndoChanges() +{ + if( !mEditor->tryToRevertToPristineState() ) + { + LLNotificationsUtil::add("ScriptCannotUndo", LLSD(), LLSD(), boost::bind(&LLScriptEdCore::handleReloadFromServerDialog, this, _1, _2)); + } +} + +// Singu TODO: modernize the menu callbacks and get rid of/update this giant block of static functions +// static +BOOL LLScriptEdCore::hasChanged(void* userdata) +{ + return static_cast(userdata)->hasChanged(); +} + // static void LLScriptEdCore::onBtnSave(void* data) { // do the save, but don't close afterwards - doSave(data, FALSE); + static_cast(data)->doSave(FALSE); } // static void LLScriptEdCore::onBtnUndoChanges( void* userdata ) { - LLScriptEdCore* self = (LLScriptEdCore*) userdata; - if( !self->mEditor->tryToRevertToPristineState() ) - { - LLNotificationsUtil::add("ScriptCannotUndo", LLSD(), LLSD(), boost::bind(&LLScriptEdCore::handleReloadFromServerDialog, self, _1, _2)); - } + static_cast(userdata)->onBtnUndoChanges(); } void LLScriptEdCore::onSearchMenu(void* userdata) @@ -1238,6 +1170,85 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask) return FALSE; } +/// --------------------------------------------------------------------------- +/// LLScriptEdContainer +/// --------------------------------------------------------------------------- + +LLScriptEdContainer::LLScriptEdContainer(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_id, const LLUUID& object_id) +: LLPreview(name, rect, title, item_id, object_id, TRUE, SCRIPT_MIN_WIDTH, SCRIPT_MIN_HEIGHT) +, mScriptEd(NULL) +{ +} + +std::string LLScriptEdContainer::getTmpFileName() +{ + // Take script inventory item id (within the object inventory) + // to consideration so that it's possible to edit multiple scripts + // in the same object inventory simultaneously (STORM-781). + std::string script_id = mObjectUUID.asString() + "_" + mItemUUID.asString(); + + // Use MD5 sum to make the file name shorter and not exceed maximum path length. + char script_id_hash_str[33]; /* Flawfinder: ignore */ + LLMD5 script_id_hash((const U8 *)script_id.c_str()); + script_id_hash.hex_digest(script_id_hash_str); + + return std::string(LLFile::tmpdir()) + "sl_script_" + script_id_hash_str + ".lsl"; +} + +bool LLScriptEdContainer::onExternalChange(const std::string& filename) +{ + if (!mScriptEd->loadScriptText(filename)) + { + return false; + } + + // Disable sync to avoid recursive load->save->load calls. + saveIfNeeded(false); + return true; +} + +// virtual +void LLScriptEdContainer::reshape(S32 width, S32 height, BOOL called_from_parent) +{ + LLPreview::reshape(width, height, called_from_parent); + + if (!isMinimized()) + { + // So that next time you open a script it will have the same height and width (although not the same position). + gSavedSettings.setRect("PreviewScriptRect", getRect()); + } +} + +// +// virtual +BOOL LLScriptEdContainer::canSaveAs() const +{ + return TRUE; +} + +// virtual +void LLScriptEdContainer::saveAs() +{ + std::string default_filename("untitled.lsl"); + if (const LLInventoryItem* item = getItem()) + { + default_filename = LLDir::getScrubbedFileName(item->getName()); + } + + AIFilePicker* filepicker = AIFilePicker::create(); + filepicker->open(default_filename, FFSAVE_SCRIPT); + filepicker->run(boost::bind(&LLLiveLSLEditor::saveAs_continued, this, filepicker)); +} + +void LLScriptEdContainer::saveAs_continued(AIFilePicker* filepicker) +{ + if (!filepicker->hasFilename()) return; + LLFILE* fp = LLFile::fopen(filepicker->getFilename(), "wb"); + fputs(mScriptEd->mEditor->getText().c_str(), fp); + fclose(fp); +} +// + /// --------------------------------------------------------------------------- /// LLPreviewLSL /// --------------------------------------------------------------------------- @@ -1260,65 +1271,50 @@ void* LLPreviewLSL::createScriptEdPanel(void* userdata) LLPreviewLSL *self = (LLPreviewLSL*)userdata; - self->mScriptEd = new LLScriptEdCore("script panel", - LLRect(), + self->mScriptEd = new LLScriptEdCore( + self, HELLO_LSL, - HELP_LSL_URL, self->getHandle(), LLPreviewLSL::onLoad, LLPreviewLSL::onSave, LLPreviewLSL::onSearchReplace, self, - self->mObjectID, - self->mItemUUID, 0); return self->mScriptEd; } -LLPreviewLSL::LLPreviewLSL(const std::string& name, const LLRect& rect, - const std::string& title, const LLUUID& item_id ) -: LLPreview( name, rect, title, item_id, LLUUID::null, TRUE, - SCRIPT_MIN_WIDTH, SCRIPT_MIN_HEIGHT ), - mPendingUploads(0) +LLPreviewLSL::LLPreviewLSL(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_id ) +: LLScriptEdContainer(name, rect, title, item_id), + mPendingUploads(0) { + mFactoryMap["script panel"] = LLCallbackMap(LLPreviewLSL::createScriptEdPanel, this); + LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_preview.xml", &getFactoryMap()); +} - LLRect curRect = rect; - - - LLCallbackMap::map_t factory_map; - factory_map["script panel"] = LLCallbackMap(LLPreviewLSL::createScriptEdPanel, this); - - - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_script_preview.xml", &factory_map); - +// virtual +BOOL LLPreviewLSL::postBuild() +{ const LLInventoryItem* item = getItem(); + llassert(item); + if (item) + { + getChild("desc")->setValue(item->getDescription()); + } childSetCommitCallback("desc", LLPreview::onText, this); - childSetText("desc", item->getDescription()); getChild("desc")->setPrevalidate(&LLLineEditor::prevalidatePrintableNotPipe); - if (!getFloaterHost() && !getHost() && getAssetStatus() == PREVIEW_ASSET_UNLOADED) - { - loadAsset(); - } - - setTitle(title); - - if (!getHost()) - { - reshape(curRect.getWidth(), curRect.getHeight(), TRUE); - setRect(curRect); - } + return LLPreview::postBuild(); } // virtual void LLPreviewLSL::callbackLSLCompileSucceeded() { llinfos << "LSL Bytecode saved" << llendl; - mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("CompileSuccessful")); - mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("SaveComplete")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessful")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete")); closeIfNeeded(); } @@ -1334,7 +1330,6 @@ void LLPreviewLSL::callbackLSLCompileFailed(const LLSD& compile_errors) LLSD row; std::string error_message = line->asString(); LLStringUtil::stripNonprintable(error_message); - row["columns"][0]["column"] = "default_column"; row["columns"][0]["value"] = error_message; row["columns"][0]["font"] = "OCRA"; mScriptEd->mErrorList->addElement(row); @@ -1383,16 +1378,16 @@ void LLPreviewLSL::loadAsset() { mScriptEd->setScriptText(mScriptEd->getString("can_not_view"), FALSE); mScriptEd->mEditor->makePristine(); - mScriptEd->mEditor->setEnabled(FALSE); mScriptEd->mFunctions->setEnabled(FALSE); mAssetStatus = PREVIEW_ASSET_LOADED; } - childSetVisible("lock", !is_modifiable); - mScriptEd->childSetEnabled("Insert...", is_modifiable); + getChildView("lock")->setVisible( !is_modifiable); + mScriptEd->getChildView("Insert...")->setEnabled(is_modifiable); } else { mScriptEd->setScriptText(std::string(HELLO_LSL), TRUE); + mScriptEd->setEnableEditing(TRUE); mAssetStatus = PREVIEW_ASSET_LOADED; } } @@ -1410,20 +1405,10 @@ void LLPreviewLSL::closeIfNeeded() mPendingUploads--; if (mPendingUploads <= 0 && mCloseAfterSave) { - if( !mScriptEd->mAutosaveFilename.empty()) { - llinfos << "remove autosave: " << mScriptEd->mAutosaveFilename << llendl; - LLFile::remove(mScriptEd->mAutosaveFilename.c_str()); - } close(); } } -//override the llpreview open which attempts to load asset, load after xml ui made -void LLPreviewLSL::open() /*Flawfinder: ignore*/ -{ - LLFloater::open(); /*Flawfinder: ignore*/ -} - void LLPreviewLSL::onSearchReplace(void* userdata) { LLPreviewLSL* self = (LLPreviewLSL*)userdata; @@ -1452,10 +1437,10 @@ void LLPreviewLSL::onSave(void* userdata, BOOL close_after_save) // Save needs to compile the text in the buffer. If the compile // succeeds, then save both assets out to the database. If the compile // fails, go ahead and save the text anyway. -void LLPreviewLSL::saveIfNeeded() +void LLPreviewLSL::saveIfNeeded(bool sync /*= true*/) { // llinfos << "LLPreviewLSL::saveIfNeeded()" << llendl; - if(!LLScriptEdCore::hasChanged(mScriptEd)) + if(!mScriptEd->hasChanged()) { return; } @@ -1471,20 +1456,13 @@ void LLPreviewLSL::saveIfNeeded() std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id.asString()); std::string filename = filepath + ".lsl"; - LLFILE* fp = LLFile::fopen(filename, "wb"); - if(!fp) + mScriptEd->writeToFile(filename); + + if (sync) { - llwarns << "Unable to write to " << filename << llendl; - - mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("CompileQueueProblemWriting")); - return; + mScriptEd->sync(); } - std::string utf8text = mScriptEd->mEditor->getText(); - fputs(utf8text.c_str(), fp); - fclose(fp); - fp = NULL; - const LLInventoryItem *inv_item = getItem(); // save it out to asset server std::string url = gAgent.getRegion()->getCapability("UpdateScriptAgent"); @@ -1499,7 +1477,7 @@ void LLPreviewLSL::saveIfNeeded() else { LLSD row; - mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("CompileQueueProblemUploading")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileQueueProblemUploading")); LLFile::remove(filename); } #if 0 //Client side compiling disabled. @@ -1614,6 +1592,7 @@ void LLPreviewLSL::uploadAssetLegacy(const std::string& filename, LLFile::remove(dst_filename); } + // static void LLPreviewLSL::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) { @@ -1640,7 +1619,7 @@ void LLPreviewLSL::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32 } // Find our window and close it if requested. - LLPreviewLSL* self = (LLPreviewLSL*)LLPreview::find(info->mItemUUID); + LLPreviewLSL* self = static_cast(LLPreview::find(info->mItemUUID)); if (self) { getWindow()->decBusyCount(); @@ -1670,7 +1649,7 @@ void LLPreviewLSL::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_d LLPreviewLSL* self = NULL; if(instance_uuid) { - self = LLPreviewLSL::getInstance(*instance_uuid); + self = static_cast(LLPreview::find(*instance_uuid)); } if (0 == status) { @@ -1709,7 +1688,7 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset lldebugs << "LLPreviewLSL::onLoadComplete: got uuid " << asset_uuid << llendl; LLUUID* item_uuid = (LLUUID*)user_data; - LLPreviewLSL* preview = LLPreviewLSL::getInstance(*item_uuid); + LLPreviewLSL* preview = static_cast(LLPreview::find(*item_uuid)); if( preview ) { if(0 == status) @@ -1733,7 +1712,7 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset { is_modifiable = TRUE; } - preview->mScriptEd->mEditor->setEnabled(is_modifiable); + preview->mScriptEd->setEnableEditing(is_modifiable); preview->mAssetStatus = PREVIEW_ASSET_LOADED; } else @@ -1761,69 +1740,11 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset delete item_uuid; } -// static -LLPreviewLSL* LLPreviewLSL::getInstance( const LLUUID& item_uuid ) -{ - LLPreview* instance = NULL; - preview_map_t::iterator found_it = LLPreview::sInstances.find(item_uuid); - if(found_it != LLPreview::sInstances.end()) - { - instance = found_it->second; - } - return (LLPreviewLSL*)instance; -} -void LLPreviewLSL::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - LLPreview::reshape( width, height, called_from_parent ); - - if( !isMinimized() ) - { - // So that next time you open a script it will have the same height and width - // (although not the same position). - gSavedSettings.setRect("PreviewScriptRect", getRect()); - } -} -// -// virtual -BOOL LLPreviewLSL::canSaveAs() const -{ - return TRUE; -} - -// virtual -void LLPreviewLSL::saveAs() -{ - std::string default_filename("untitled.lsl"); - const LLInventoryItem *item = getItem(); - if(item) - { - default_filename = LLDir::getScrubbedFileName(item->getName()) + ".lsl"; - } - - AIFilePicker* filepicker = AIFilePicker::create(); - filepicker->open(default_filename, FFSAVE_SCRIPT); - filepicker->run(boost::bind(&LLPreviewLSL::saveAs_continued, this, filepicker)); -} - -void LLPreviewLSL::saveAs_continued(AIFilePicker* filepicker) -{ - if(!filepicker->hasFilename()) - return; - - std::string utf8text = mScriptEd->mEditor->getText(); - LLFILE* fp = LLFile::fopen(filepicker->getFilename(), "wb"); - fputs(utf8text.c_str(), fp); - fclose(fp); -} -// /// --------------------------------------------------------------------------- /// LLLiveLSLEditor /// --------------------------------------------------------------------------- -LLMap LLLiveLSLEditor::sInstances; - - //static void* LLLiveLSLEditor::createScriptEdPanel(void* userdata) @@ -1831,89 +1752,49 @@ void* LLLiveLSLEditor::createScriptEdPanel(void* userdata) LLLiveLSLEditor *self = (LLLiveLSLEditor*)userdata; - self->mScriptEd = new LLScriptEdCore("script ed panel", - LLRect(), + self->mScriptEd = new LLScriptEdCore( + self, HELLO_LSL, - HELP_LSL_URL, self->getHandle(), &LLLiveLSLEditor::onLoad, &LLLiveLSLEditor::onSave, &LLLiveLSLEditor::onSearchReplace, self, - self->mObjectID, - self->mItemUUID, 0); return self->mScriptEd; } -LLLiveLSLEditor::LLLiveLSLEditor(const std::string& name, - const LLRect& rect, - const std::string& title, - const LLUUID& object_id, - const LLUUID& item_id) : - LLPreview(name, rect, title, item_id, object_id, TRUE, SCRIPT_MIN_WIDTH, SCRIPT_MIN_HEIGHT), - mObjectID(object_id), - mItemID(item_id), - mScriptEd(NULL), +LLLiveLSLEditor::LLLiveLSLEditor(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& object_id, const LLUUID& item_id) : + LLScriptEdContainer(name, rect, title, item_id, object_id), mAskedForRunningInfo(FALSE), mHaveRunningInfo(FALSE), mCloseAfterSave(FALSE), mPendingUploads(0), - mIsModifiable(FALSE) + mIsModifiable(FALSE), + mIsNew(false) { + mFactoryMap["script ed panel"] = LLCallbackMap(LLLiveLSLEditor::createScriptEdPanel, this); + LLUICtrlFactory::getInstance()->buildFloater(this,"floater_live_lsleditor.xml", &getFactoryMap()); +} - - BOOL is_new = FALSE; - if(mItemID.isNull()) - { - mItemID.generate(); - is_new = TRUE; - } - - - LLLiveLSLEditor::sInstances.addData(mItemID ^ mObjectID, this); - - LLCallbackMap::map_t factory_map; - factory_map["script ed panel"] = LLCallbackMap(LLLiveLSLEditor::createScriptEdPanel, this); - - LLUICtrlFactory::getInstance()->buildFloater(this,"floater_live_lsleditor.xml", &factory_map); - - mMonoCheckbox = getChild("mono"); - childSetCommitCallback("mono", &LLLiveLSLEditor::onMonoCheckboxClicked, this); - childSetEnabled("mono", FALSE); - +BOOL LLLiveLSLEditor::postBuild() +{ childSetCommitCallback("running", LLLiveLSLEditor::onRunningCheckboxClicked, this); - childSetEnabled("running", FALSE); + getChildView("running")->setEnabled(FALSE); childSetAction("Reset",&LLLiveLSLEditor::onReset,this); - childSetEnabled("Reset", TRUE); + getChildView("Reset")->setEnabled(TRUE); + mMonoCheckbox = getChild("mono"); + childSetCommitCallback("mono", &LLLiveLSLEditor::onMonoCheckboxClicked, this); + getChildView("mono")->setEnabled(FALSE); mScriptEd->mEditor->makePristine(); - loadAsset(is_new); mScriptEd->mEditor->setFocus(TRUE); - - if (!getHost()) - { - LLRect curRect = getRect(); - translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop); - } - - setTitle(title); -} - -LLLiveLSLEditor::~LLLiveLSLEditor() -{ - LLLiveLSLEditor::sInstances.removeData(mItemID ^ mObjectID); -} - -// this is called via LLPreview::loadAsset() virtual method -void LLLiveLSLEditor::loadAsset() -{ - loadAsset(FALSE); + return LLPreview::postBuild(); } // virtual @@ -1922,8 +1803,8 @@ void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id, bool is_script_running) { lldebugs << "LSL Bytecode saved" << llendl; - mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("CompileSuccessful")); - mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("SaveComplete")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileSuccessful")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete")); closeIfNeeded(); } @@ -1938,8 +1819,8 @@ void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors) LLSD row; std::string error_message = line->asString(); LLStringUtil::stripNonprintable(error_message); - row["columns"][0]["column"] = "default_column"; row["columns"][0]["value"] = error_message; + // *TODO: change to "MONOSPACE" and change llfontgl.cpp? row["columns"][0]["font"] = "OCRA"; mScriptEd->mErrorList->addElement(row); } @@ -1947,16 +1828,15 @@ void LLLiveLSLEditor::callbackLSLCompileFailed(const LLSD& compile_errors) closeIfNeeded(); } -void LLLiveLSLEditor::loadAsset(BOOL is_new) +void LLLiveLSLEditor::loadAsset() { //llinfos << "LLLiveLSLEditor::loadAsset()" << llendl; - if(!is_new) + if(!mIsNew) { - LLViewerObject* object = gObjectList.findObject(mObjectID); + LLViewerObject* object = gObjectList.findObject(mObjectUUID); if(object) { - // HACK! we "know" that mItemID refers to a LLViewerInventoryItem... - LLViewerInventoryItem* item = (LLViewerInventoryItem*)object->getInventoryObject(mItemID); + LLViewerInventoryItem* item = dynamic_cast(object->getInventoryObject(mItemUUID)); if(item && (gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE) || gAgent.isGodlike())) @@ -1973,14 +1853,13 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new) mItem = new LLViewerInventoryItem(item); mScriptEd->setScriptText(getString("not_allowed"), FALSE); mScriptEd->mEditor->makePristine(); - mScriptEd->mEditor->setEnabled(FALSE); mScriptEd->enableSave(FALSE); mAssetStatus = PREVIEW_ASSET_LOADED; } else if(item && mItem.notNull()) { // request the text from the object - LLUUID* user_data = new LLUUID(mItemID ^ mObjectID); + LLUUID* user_data = new LLUUID(mItemUUID); // ^ mObjectUUID gAssetStorage->getInvItemAsset(object->getRegion()->getHost(), gAgent.getID(), gAgent.getSessionID(), @@ -1995,8 +1874,8 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new) LLMessageSystem* msg = gMessageSystem; msg->newMessageFast(_PREHASH_GetScriptRunning); msg->nextBlockFast(_PREHASH_Script); - msg->addUUIDFast(_PREHASH_ObjectID, mObjectID); - msg->addUUIDFast(_PREHASH_ItemID, mItemID); + msg->addUUIDFast(_PREHASH_ObjectID, mObjectUUID); + msg->addUUIDFast(_PREHASH_ItemID, mItemUUID); msg->sendReliable(object->getRegion()->getHost()); mAskedForRunningInfo = TRUE; mAssetStatus = PREVIEW_ASSET_LOADING; @@ -2011,10 +1890,6 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new) mIsModifiable = item && gAgent.allowOperation(PERM_MODIFY, item->getPermissions(), GP_OBJECT_MANIPULATE); - if(!mIsModifiable) - { - mScriptEd->mEditor->setEnabled(FALSE); - } // This is commented out, because we don't completely // handle script exports yet. @@ -2025,26 +1900,12 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new) gMessageSystem->addUUID("AgentID", gAgent.getID()); U32 local_id = object->getLocalID(); gMessageSystem->addData("LocalID", &local_id); - gMessageSystem->addUUID("ItemID", mItemID); + gMessageSystem->addUUID("ItemID", mItemUUID); LLHost host(object->getRegion()->getIP(), object->getRegion()->getPort()); gMessageSystem->sendReliable(host); */ } - - // Initialization of the asset failed. Probably the result - // of a bug somewhere else. Set up this editor in a no-go mode. - if(mItem.isNull()) - { - // Set the inventory item to an incomplete item. - // This may be better than having a accessible null pointer around, - // though this newly allocated object will most likely be replaced. - mItem = new LLViewerInventoryItem(); - mScriptEd->setScriptText(LLStringUtil::null, FALSE); - mScriptEd->mEditor->makePristine(); - mScriptEd->mEditor->setEnabled(FALSE); - mAssetStatus = PREVIEW_ASSET_LOADED; - } } else { @@ -2053,17 +1914,17 @@ void LLLiveLSLEditor::loadAsset(BOOL is_new) LLPermissions perm; perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, gAgent.getGroupID()); perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, PERM_MOVE | PERM_TRANSFER); - mItem = new LLViewerInventoryItem(mItemID, - mObjectID, - perm, - LLUUID::null, - LLAssetType::AT_LSL_TEXT, - LLInventoryType::IT_LSL, - DEFAULT_SCRIPT_NAME, - DEFAULT_SCRIPT_DESC, - LLSaleInfo::DEFAULT, - LLInventoryItemFlags::II_FLAGS_NONE, - time_corrected()); + mItem = new LLViewerInventoryItem(mItemUUID, + mObjectUUID, + perm, + LLUUID::null, + LLAssetType::AT_LSL_TEXT, + LLInventoryType::IT_LSL, + DEFAULT_SCRIPT_NAME, + DEFAULT_SCRIPT_DESC, + LLSaleInfo::DEFAULT, + LLInventoryItemFlags::II_FLAGS_NONE, + time_corrected()); mAssetStatus = PREVIEW_ASSET_LOADED; } } @@ -2075,15 +1936,16 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id, { lldebugs << "LLLiveLSLEditor::onLoadComplete: got uuid " << asset_id << llendl; - LLLiveLSLEditor* instance = NULL; LLUUID* xored_id = (LLUUID*)user_data; - if( LLLiveLSLEditor::sInstances.checkData(*xored_id) ) + LLLiveLSLEditor* instance = static_cast(LLPreview::find(*xored_id)); + + if(instance ) { - instance = LLLiveLSLEditor::sInstances[*xored_id]; if( LL_ERR_NOERR == status ) { instance->loadScriptText(vfs, asset_id, type); + instance->mScriptEd->setEnableEditing(TRUE); instance->mAssetStatus = PREVIEW_ASSET_LOADED; } else @@ -2110,39 +1972,6 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id, delete xored_id; } -// unused -// void LLLiveLSLEditor::loadScriptText(const std::string& filename) -// { -// if(!filename) -// { -// llerrs << "Filename is Empty!" << llendl; -// return; -// } -// LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/ -// if(file) -// { -// // read in the whole file -// fseek(file, 0L, SEEK_END); -// long file_length = ftell(file); -// fseek(file, 0L, SEEK_SET); -// char* buffer = new char[file_length+1]; -// size_t nread = fread(buffer, 1, file_length, file); -// if (nread < (size_t) file_length) -// { -// llwarns << "Short read" << llendl; -// } -// buffer[nread] = '\0'; -// fclose(file); -// mScriptEd->mEditor->setText(LLStringExplicit(buffer)); -// mScriptEd->mEditor->makePristine(); -// delete[] buffer; -// } -// else -// { -// llwarns << "Error opening " << filename << llendl; -// } -// } - void LLLiveLSLEditor::loadScriptText(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type) { LLVFile file(vfs, uuid, type); @@ -2161,14 +1990,13 @@ void LLLiveLSLEditor::loadScriptText(LLVFS *vfs, const LLUUID &uuid, LLAssetType mScriptEd->setScriptText(LLStringExplicit(&buffer[0]), TRUE); mScriptEd->mEditor->makePristine(); delete[] buffer; - } void LLLiveLSLEditor::onRunningCheckboxClicked( LLUICtrl*, void* userdata ) { LLLiveLSLEditor* self = (LLLiveLSLEditor*) userdata; - LLViewerObject* object = gObjectList.findObject( self->mObjectID ); + LLViewerObject* object = gObjectList.findObject( self->mObjectUUID ); LLCheckBoxCtrl* runningCheckbox = self->getChild("running"); BOOL running = runningCheckbox->get(); //self->mRunningCheckbox->get(); @@ -2187,8 +2015,8 @@ void LLLiveLSLEditor::onRunningCheckboxClicked( LLUICtrl*, void* userdata ) msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_Script); - msg->addUUIDFast(_PREHASH_ObjectID, self->mObjectID); - msg->addUUIDFast(_PREHASH_ItemID, self->mItemID); + msg->addUUIDFast(_PREHASH_ObjectID, self->mObjectUUID); + msg->addUUIDFast(_PREHASH_ItemID, self->mItemUUID); msg->addBOOLFast(_PREHASH_Running, running); msg->sendReliable(object->getRegion()->getHost()); } @@ -2203,7 +2031,7 @@ void LLLiveLSLEditor::onReset(void *userdata) { LLLiveLSLEditor* self = (LLLiveLSLEditor*) userdata; - LLViewerObject* object = gObjectList.findObject( self->mObjectID ); + LLViewerObject* object = gObjectList.findObject( self->mObjectUUID ); if(object) { // [RLVa:KB] - Checked: 2010-09-28 (RLVa-1.2.1f) | Modified: RLVa-1.0.5a @@ -2219,8 +2047,8 @@ void LLLiveLSLEditor::onReset(void *userdata) msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID()); msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); msg->nextBlockFast(_PREHASH_Script); - msg->addUUIDFast(_PREHASH_ObjectID, self->mObjectID); - msg->addUUIDFast(_PREHASH_ItemID, self->mItemID); + msg->addUUIDFast(_PREHASH_ObjectID, self->mObjectUUID); + msg->addUUIDFast(_PREHASH_ItemID, self->mItemUUID); msg->sendReliable(object->getRegion()->getHost()); } else @@ -2231,7 +2059,7 @@ void LLLiveLSLEditor::onReset(void *userdata) void LLLiveLSLEditor::draw() { - LLViewerObject* object = gObjectList.findObject(mObjectID); + LLViewerObject* object = gObjectList.findObject(mObjectUUID); LLCheckBoxCtrl* runningCheckbox = getChild( "running"); if(object && mAskedForRunningInfo && mHaveRunningInfo) { @@ -2282,7 +2110,7 @@ void LLLiveLSLEditor::draw() mHaveRunningInfo = FALSE; } - LLFloater::draw(); + LLPreview::draw(); } @@ -2300,7 +2128,7 @@ void LLLiveLSLEditor::onSearchReplace(void* userdata) struct LLLiveLSLSaveData { LLLiveLSLSaveData(const LLUUID& id, const LLViewerInventoryItem* item, BOOL active); - LLUUID mObjectID; + LLUUID mSaveObjectID; LLPointer mItem; BOOL mActive; }; @@ -2308,24 +2136,24 @@ struct LLLiveLSLSaveData LLLiveLSLSaveData::LLLiveLSLSaveData(const LLUUID& id, const LLViewerInventoryItem* item, BOOL active) : - mObjectID(id), + mSaveObjectID(id), mActive(active) { llassert(item); mItem = new LLViewerInventoryItem(item); } -void LLLiveLSLEditor::saveIfNeeded() +// virtual +void LLLiveLSLEditor::saveIfNeeded(bool sync /*= true*/) { - llinfos << "LLLiveLSLEditor::saveIfNeeded()" << llendl; - LLViewerObject* object = gObjectList.findObject(mObjectID); + LLViewerObject* object = gObjectList.findObject(mObjectUUID); if(!object) { LLNotificationsUtil::add("SaveScriptFailObjectNotFound"); return; } - if(mItem.isNull() || !mItem->isComplete()) + if(mItem.isNull() || !mItem->isFinished()) { // $NOTE: While the error message may not be exactly correct, // it's pretty close. @@ -2344,15 +2172,14 @@ void LLLiveLSLEditor::saveIfNeeded() // name on save, because the viewer object version of the item, // and the editor version would get out of synch. Here's a good // place to synch them back up. - // HACK! we "know" that mItemID refers to a LLInventoryItem... - LLInventoryItem* inv_item = (LLInventoryItem*)object->getInventoryObject(mItemID); + LLInventoryItem* inv_item = dynamic_cast(object->getInventoryObject(mItemUUID)); if(inv_item) { mItem->copyItem(inv_item); } // Don't need to save if we're pristine - if(!LLScriptEdCore::hasChanged(mScriptEd)) + if(!mScriptEd->hasChanged()) { return; } @@ -2375,26 +2202,12 @@ void LLLiveLSLEditor::saveIfNeeded() mItem->setAssetUUID(asset_id); mItem->setTransactionID(tid); - // write out the data, and store it in the asset database - LLFILE* fp = LLFile::fopen(filename, "wb"); - if(!fp) + mScriptEd->writeToFile(filename); + + if (sync) { - llwarns << "Unable to write to " << filename << llendl; - - mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("CompileQueueProblemWriting")); - return; + mScriptEd->sync(); } - std::string utf8text = mScriptEd->mEditor->getText(); - - // Special case for a completely empty script - stuff in one space so it can store properly. See SL-46889 - if ( utf8text.size() == 0 ) - { - utf8text = " "; - } - - fputs(utf8text.c_str(), fp); - fclose(fp); - fp = NULL; // save it out to asset server std::string url = object->getRegion()->getCapability("UpdateScriptTask"); @@ -2403,12 +2216,11 @@ void LLLiveLSLEditor::saveIfNeeded() BOOL is_running = getChild( "running")->get(); if (!url.empty()) { - uploadAssetViaCaps(url, filename, mObjectID, - mItemID, is_running); + uploadAssetViaCaps(url, filename, mObjectUUID, mItemUUID, is_running); } else { - mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("CompileQueueProblemUploading")); + mScriptEd->mErrorList->setCommentText(LLTrans::getString("CompileQueueProblemUploading")); LLFile::remove(filename); } #if 0 //Client side compiling disabled. @@ -2425,7 +2237,7 @@ void LLLiveLSLEditor::uploadAssetViaCaps(const std::string& url, const LLUUID& item_id, BOOL is_running) { - llinfos << "Update Task Inventory via capability" << llendl; + llinfos << "Update Task Inventory via capability " << url << llendl; LLSD body; body["task_id"] = task_id; body["item_id"] = item_id; @@ -2441,7 +2253,7 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename, const LLTransactionID& tid, BOOL is_running) { - LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectID, + LLLiveLSLSaveData* data = new LLLiveLSLSaveData(mObjectUUID, mItem, is_running); gAssetStorage->storeAssetData(filename, tid, @@ -2512,7 +2324,7 @@ void LLLiveLSLEditor::uploadAssetLegacy(const std::string& filename, getWindow()->incBusyCount(); mPendingUploads++; LLLiveLSLSaveData* data = NULL; - data = new LLLiveLSLSaveData(mObjectID, + data = new LLLiveLSLSaveData(mObjectUUID, mItem, is_running); gAssetStorage->storeAssetData(dst_filename, @@ -2548,7 +2360,7 @@ void LLLiveLSLEditor::onSaveTextComplete(const LLUUID& asset_uuid, void* user_da } else { - LLLiveLSLEditor* self = sInstances.getIfThere(data->mItem->getUUID() ^ data->mObjectID); + LLLiveLSLEditor* self = static_cast(LLPreview::find(data->mItem->getUUID())); // ^ data->mSaveObjectID if (self) { self->getWindow()->decBusyCount(); @@ -2564,6 +2376,7 @@ void LLLiveLSLEditor::onSaveTextComplete(const LLUUID& asset_uuid, void* user_da data = NULL; } + void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed) { LLLiveLSLSaveData* data = (LLLiveLSLSaveData*)user_data; @@ -2572,12 +2385,11 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use if(0 ==status) { llinfos << "LSL Bytecode saved" << llendl; - LLUUID xor_id = data->mItem->getUUID() ^ data->mObjectID; - LLLiveLSLEditor* self = sInstances.getIfThere(xor_id); + LLLiveLSLEditor* self = static_cast(LLPreview::find(data->mItem->getUUID())); // ^ data->mSaveObjectID if(self) { // Tell the user that the compile worked. - self->mScriptEd->mErrorList->addSimpleElement(LLTrans::getString("SaveComplete")); + self->mScriptEd->mErrorList->setCommentText(LLTrans::getString("SaveComplete")); // close the window if this completes both uploads self->getWindow()->decBusyCount(); self->mPendingUploads--; @@ -2587,7 +2399,7 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use self->close(); } } - LLViewerObject* object = gObjectList.findObject(data->mObjectID); + LLViewerObject* object = gObjectList.findObject(data->mSaveObjectID); if(object) { object->saveScript(data->mItem, data->mActive, false); @@ -2613,11 +2425,6 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use } #endif -void LLLiveLSLEditor::open() -{ - LLFloater::open(); /*Flawfinder: ignore*/ -} - BOOL LLLiveLSLEditor::canClose() { return (mScriptEd->canClose()); @@ -2629,10 +2436,6 @@ void LLLiveLSLEditor::closeIfNeeded() mPendingUploads--; if (mPendingUploads <= 0 && mCloseAfterSave) { - if( !mScriptEd->mAutosaveFilename.empty()) { - llinfos << "remove autosave: " << mScriptEd->mAutosaveFilename << llendl; - LLFile::remove(mScriptEd->mAutosaveFilename.c_str()); - } close(); } } @@ -2648,46 +2451,10 @@ void LLLiveLSLEditor::onLoad(void* userdata) void LLLiveLSLEditor::onSave(void* userdata, BOOL close_after_save) { LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata; - self->mCloseAfterSave = close_after_save; self->saveIfNeeded(); } -// static -LLLiveLSLEditor* LLLiveLSLEditor::show(const LLUUID& script_id, const LLUUID& object_id) -{ - LLLiveLSLEditor* instance = NULL; - LLUUID xored_id = script_id ^ object_id; - if(LLLiveLSLEditor::sInstances.checkData(xored_id)) - { - // Move the existing view to the front - instance = LLLiveLSLEditor::sInstances[xored_id]; - instance->open(); /*Flawfinder: ignore*/ - } - return instance; -} - -// static -void LLLiveLSLEditor::hide(const LLUUID& script_id, const LLUUID& object_id) -{ - LLUUID xored_id = script_id ^ object_id; - if( LLLiveLSLEditor::sInstances.checkData( xored_id ) ) - { - LLLiveLSLEditor* instance = LLLiveLSLEditor::sInstances[xored_id]; - if(instance->getParent()) - { - instance->getParent()->removeChild(instance); - } - delete instance; - } -} -// static -LLLiveLSLEditor* LLLiveLSLEditor::find(const LLUUID& script_id, const LLUUID& object_id) -{ - LLUUID xored_id = script_id ^ object_id; - return sInstances.getIfThere(xored_id); -} - // static void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**) @@ -2696,10 +2463,10 @@ void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**) LLUUID object_id; msg->getUUIDFast(_PREHASH_Script, _PREHASH_ObjectID, object_id); msg->getUUIDFast(_PREHASH_Script, _PREHASH_ItemID, item_id); - LLUUID xored_id = item_id ^ object_id; - if(LLLiveLSLEditor::sInstances.checkData(xored_id)) + + LLLiveLSLEditor* instance = static_cast(LLPreview::find(item_id)); // ^ object_id + if(instance) { - LLLiveLSLEditor* instance = LLLiveLSLEditor::sInstances[xored_id]; instance->mHaveRunningInfo = TRUE; BOOL running; msg->getBOOLFast(_PREHASH_Script, _PREHASH_Running, running); @@ -2713,22 +2480,11 @@ void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**) } } -void LLLiveLSLEditor::reshape(S32 width, S32 height, BOOL called_from_parent) -{ - LLFloater::reshape( width, height, called_from_parent ); - - if( !isMinimized() ) - { - // So that next time you open a script it will have the same height and width - // (although not the same position). - gSavedSettings.setRect("PreviewScriptRect", getRect()); - } -} void LLLiveLSLEditor::onMonoCheckboxClicked(LLUICtrl*, void* userdata) { LLLiveLSLEditor* self = static_cast(userdata); - self->mMonoCheckbox->setEnabled(have_script_upload_cap(self->mObjectID)); + self->mMonoCheckbox->setEnabled(have_script_upload_cap(self->mObjectUUID)); self->mScriptEd->enableSave(self->getIsModifiable()); } @@ -2739,38 +2495,4 @@ BOOL LLLiveLSLEditor::monoChecked() const return mMonoCheckbox->getValue()? TRUE : FALSE; } return FALSE; -} - -// -// virtual -BOOL LLLiveLSLEditor::canSaveAs() const -{ - return TRUE; -} - -// virtual -void LLLiveLSLEditor::saveAs() -{ - std::string default_filename("untitled.lsl"); - const LLInventoryItem *item = getItem(); - if(item) - { - default_filename = LLDir::getScrubbedFileName(item->getName()); - } - - AIFilePicker* filepicker = AIFilePicker::create(); - filepicker->open(default_filename, FFSAVE_SCRIPT); - filepicker->run(boost::bind(&LLLiveLSLEditor::saveAs_continued, this, filepicker)); -} - -void LLLiveLSLEditor::saveAs_continued(AIFilePicker* filepicker) -{ - if (!filepicker->hasFilename()) - return; - - std::string utf8text = mScriptEd->mEditor->getText(); - LLFILE* fp = LLFile::fopen(filepicker->getFilename(), "wb"); - fputs(utf8text.c_str(), fp); - fclose(fp); -} -// +} \ No newline at end of file diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h index 9b171763f..396b4f651 100644 --- a/indra/newview/llpreviewscript.h +++ b/indra/newview/llpreviewscript.h @@ -40,7 +40,6 @@ #include "llcombobox.h" #include "lliconctrl.h" #include "llframetimer.h" -#include "lleventtimer.h" class LLLiveLSLFile; class LLMessageSystem; @@ -55,56 +54,59 @@ class LLKeywordToken; class AIFilePicker; // Inner, implementation class. LLPreviewScript and LLLiveLSLEditor each own one of these. -class LLScriptEdCore : public LLPanel, public LLEventTimer +class LLScriptEdCore : public LLPanel { friend class LLPreviewScript; friend class LLPreviewLSL; friend class LLLiveLSLEditor; + friend class LLFloaterSearchReplace; + friend class LLScriptEdContainer; public: static void parseFunctions(const std::string& filename); + +protected: + // Supposed to be invoked only by the container. LLScriptEdCore( - const std::string& name, - const LLRect& rect, + LLScriptEdContainer* container, const std::string& sample, - const std::string& help_url, const LLHandle& floater_handle, void (*load_callback)(void* userdata), void (*save_callback)(void* userdata, BOOL close_after_save), void (*search_replace_callback)(void* userdata), void* userdata, - LLUUID objectUUID, - LLUUID itemUUID, S32 bottom_pad = 0); // pad below bottom row of buttons +public: ~LLScriptEdCore(); void initMenu(); virtual void draw(); - + /*virtual*/ BOOL postBuild(); BOOL canClose(); + void setEnableEditing(bool enable); void setScriptText(const std::string& text, BOOL is_valid); bool loadScriptText(const std::string& filename); bool writeToFile(const std::string& filename); void sync(); - std::string getTmpFileName(); - static void openInExternalEditor(void* userdata); - bool onExternalChange(const std::string& filename); + + void doSave( BOOL close_after_save ); bool handleSaveChangesDialog(const LLSD& notification, const LLSD& response); bool handleReloadFromServerDialog(const LLSD& notification, const LLSD& response); - static bool onHelpWebDialog(const LLSD& notification, const LLSD& response); - static void onBtnHelp(void* userdata); - static void onBtnDynamicHelp(void* userdata); + void openInExternalEditor(); + static void onCheckLock(LLUICtrl*, void*); static void onHelpComboCommit(LLUICtrl* ctrl, void* userdata); static void onClickBack(void* userdata); static void onClickForward(void* userdata); static void onBtnInsertSample(void*); static void onBtnInsertFunction(LLUICtrl*, void*); - static void doSave( void* userdata, BOOL close_after_save, BOOL sync_external_editor = TRUE ); + + // Singu TODO: modernize the menu callbacks and get rid of/update this giant block of static functions + static BOOL hasChanged(void* userdata); static void onBtnSave(void*); static void onBtnUndoChanges(void*); static void onSearchMenu(void* userdata); @@ -125,16 +127,18 @@ public: static BOOL enableSelectAllMenu(void* userdata); static BOOL enableDeselectMenu(void* userdata); - static BOOL hasChanged(void* userdata); +private: + static bool onHelpWebDialog(const LLSD& notification, const LLSD& response); + static void onBtnHelp(void* userdata); + static void onBtnDynamicHelp(void* userdata); + void onBtnUndoChanges(); + + bool hasChanged(); void selectFirstError(); - - void autoSave(); virtual BOOL handleKeyHere(KEY key, MASK mask); - virtual BOOL tick(); - void enableSave(BOOL b) {mEnableSave = b;} protected: @@ -144,12 +148,8 @@ protected: void addHelpItemToHistory(const std::string& help_string); static void onErrorList(LLUICtrl*, void* user_data); - virtual const char *getTitleName() const { return "Script"; } - private: std::string mSampleText; - std::string mAutosaveFilename; - std::string mHelpURL; LLTextEditor* mEditor; void (*mLoadCallback)(void* userdata); void (*mSaveCallback)(void* userdata, BOOL close_after_save); @@ -157,7 +157,6 @@ private: void* mUserdata; LLComboBox *mFunctions; BOOL mForceClose; - //LLPanel* mGuiPanel; LLPanel* mCodePanel; LLScrollListCtrl* mErrorList; LLDynamicArray mBridges; @@ -168,8 +167,8 @@ private: BOOL mEnableSave; BOOL mHasScriptData; LLLiveLSLFile* mLiveFile; - LLUUID mObjectUUID; - LLUUID mItemUUID; + + LLScriptEdContainer* mContainer; // parent view struct LSLFunctionProps { @@ -180,25 +179,47 @@ private: static std::vector mParsedFunctions; }; +class LLScriptEdContainer : public LLPreview +{ + friend class LLScriptEdCore; + friend class LLMultiPreview; + +public: + LLScriptEdContainer(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_id, const LLUUID& object_id = LLUUID::null); + +protected: + std::string getTmpFileName(); + bool onExternalChange(const std::string& filename); + virtual void saveIfNeeded(bool sync = true) = 0; + + LLTextEditor* getEditor() { return mScriptEd->mEditor; } + /*virtual*/ const char *getTitleName() const { return "Script"; } + /*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); + // + /*virtual*/ BOOL canSaveAs() const; + /*virtual*/ void saveAs(); + void saveAs_continued(AIFilePicker* filepicker); + // + + LLScriptEdCore* mScriptEd; +}; // Used to view and edit a LSL from your inventory. -class LLPreviewLSL : public LLPreview +class LLPreviewLSL : public LLScriptEdContainer { public: - LLPreviewLSL(const std::string& name, const LLRect& rect, const std::string& title, - const LLUUID& item_uuid ); + LLPreviewLSL(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& item_uuid ); virtual void callbackLSLCompileSucceeded(); virtual void callbackLSLCompileFailed(const LLSD& compile_errors); - /*virtual*/ void open(); /*Flawfinder: ignore*/ + /*virtual*/ BOOL postBuild(); protected: virtual BOOL canClose(); void closeIfNeeded(); - virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); virtual void loadAsset(); - void saveIfNeeded(); + /*virtual*/ void saveIfNeeded(bool sync = true); void uploadAssetViaCaps(const std::string& url, const std::string& filename, const LLUUID& item_id); @@ -207,11 +228,6 @@ protected: const LLUUID& item_id, const LLTransactionID& tid); #endif - // - virtual BOOL canSaveAs() const; - virtual void saveAs(); - void saveAs_continued(AIFilePicker* filepicker); - // static void onSearchReplace(void* userdata); static void onLoad(void* userdata); @@ -224,17 +240,13 @@ protected: static void onSaveComplete(const LLUUID& uuid, void* user_data, S32 status, LLExtStat ext_status); static void onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status); #endif -public: - static LLPreviewLSL* getInstance(const LLUUID& uuid); - LLTextEditor* getEditor() { return mScriptEd->mEditor; } + protected: static void* createScriptEdPanel(void* userdata); protected: - virtual const char *getTitleName() const { return "Script"; } - LLScriptEdCore* mScriptEd; // Can safely close only after both text and bytecode are uploaded S32 mPendingUploads; @@ -242,19 +254,13 @@ protected: // Used to view and edit an LSL that is attached to an object. -class LLLiveLSLEditor : public LLPreview +class LLLiveLSLEditor : public LLScriptEdContainer { + friend class LLLiveLSLFile; public: - LLLiveLSLEditor(const std::string& name, const LLRect& rect, - const std::string& title, - const LLUUID& object_id, const LLUUID& item_id); - ~LLLiveLSLEditor(); + LLLiveLSLEditor(const std::string& name, const LLRect& rect, const std::string& title, const LLUUID& object_id, const LLUUID& item_id); - static LLLiveLSLEditor* show(const LLUUID& item_id, const LLUUID& object_id); - static void hide(const LLUUID& item_id, const LLUUID& object_id); - static LLLiveLSLEditor* find(const LLUUID& item_id, const LLUUID& object_id); - static void processScriptRunningReply(LLMessageSystem* msg, void**); virtual void callbackLSLCompileSucceeded(const LLUUID& task_id, @@ -262,18 +268,18 @@ public: bool is_script_running); virtual void callbackLSLCompileFailed(const LLSD& compile_errors); - // Overide LLPreview::open() to avoid calling loadAsset twice. - /*virtual*/ void open(); /*Flawfinder: ignore*/ + /*virtual*/ BOOL postBuild(); -protected: + void setIsNew() { mIsNew = TRUE; } + +private: virtual BOOL canClose(); void closeIfNeeded(); virtual void draw(); - virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE); virtual void loadAsset(); void loadAsset(BOOL is_new); - void saveIfNeeded(); + /*virtual*/ void saveIfNeeded(bool sync = true); void uploadAssetViaCaps(const std::string& url, const std::string& filename, const LLUUID& task_id, @@ -285,11 +291,8 @@ protected: const LLTransactionID& tid, BOOL is_running); #endif - // - virtual BOOL canSaveAs() const; - virtual void saveAs(); - void saveAs_continued(AIFilePicker* filepicker); - // + BOOL monoChecked() const; + static void onSearchReplace(void* userdata); static void onLoad(void* userdata); @@ -305,19 +308,16 @@ protected: static void onRunningCheckboxClicked(LLUICtrl*, void* userdata); static void onReset(void* userdata); -// void loadScriptText(const std::string& filename); // unused void loadScriptText(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type); static void onErrorList(LLUICtrl*, void* user_data); static void* createScriptEdPanel(void* userdata); + static void onMonoCheckboxClicked(LLUICtrl*, void* userdata); -protected: - LLUUID mObjectID; - LLUUID mItemID; // The inventory item this script is associated with - BOOL mIsNew; - LLScriptEdCore* mScriptEd; +private: + bool mIsNew; //LLUUID mTransmitID; LLCheckBoxCtrl *mRunningCheckbox; BOOL mAskedForRunningInfo; @@ -328,14 +328,8 @@ protected: // need to save both text and script, so need to decide when done S32 mPendingUploads; - static LLMap sInstances; BOOL getIsModifiable() const { return mIsModifiable; } // Evaluated on load assert -private: - - static void onMonoCheckboxClicked(LLUICtrl*, void* userdata); - BOOL monoChecked() const; - LLCheckBoxCtrl* mMonoCheckbox; BOOL mIsModifiable; };