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; };