Automated merge up from viewer-development
commit
b30ff3fb9a
|
|
@ -801,6 +801,7 @@ WolfPup Lowenhar
|
|||
STORM-654
|
||||
STORM-674
|
||||
STORM-776
|
||||
STORM-825
|
||||
VWR-20741
|
||||
VWR-20933
|
||||
Zai Lynch
|
||||
|
|
|
|||
|
|
@ -280,7 +280,6 @@ namespace tut
|
|||
llmat_obj.setRows(llvec1, llvec2, llvec3);
|
||||
llmat_obj.orthogonalize();
|
||||
|
||||
skip("Grr, LLMatrix3::orthogonalize test is failing. Has it ever worked?");
|
||||
ensure("LLMatrix3::orthogonalize failed ",
|
||||
is_approx_equal(0.19611613f, llmat_obj.mMatrix[0][0]) &&
|
||||
is_approx_equal(0.78446454f, llmat_obj.mMatrix[0][1]) &&
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -131,7 +131,7 @@ RenderFlexTimeFactor 1 1.0
|
|||
RenderGlowResolutionPow 1 9
|
||||
RenderMaxPartCount 1 4096
|
||||
RenderObjectBump 1 1
|
||||
RenderReflectionDetail 1 2
|
||||
RenderReflectionDetail 1 0
|
||||
RenderTerrainDetail 1 1
|
||||
RenderTerrainLODFactor 1 2.0
|
||||
RenderTransparentWater 1 1
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ RenderGlowResolutionPow 1 9
|
|||
RenderLocalLights 1 1
|
||||
RenderMaxPartCount 1 4096
|
||||
RenderObjectBump 1 1
|
||||
RenderReflectionDetail 1 2
|
||||
RenderReflectionDetail 1 0
|
||||
RenderTerrainDetail 1 1
|
||||
RenderTerrainLODFactor 1 2.0
|
||||
RenderTransparentWater 1 1
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ RenderFlexTimeFactor 1 1.0
|
|||
RenderGlowResolutionPow 1 9
|
||||
RenderMaxPartCount 1 4096
|
||||
RenderObjectBump 1 1
|
||||
RenderReflectionDetail 1 2
|
||||
RenderReflectionDetail 1 0
|
||||
RenderTerrainDetail 1 1
|
||||
RenderTerrainLODFactor 1 2.0
|
||||
RenderTransparentWater 1 1
|
||||
|
|
|
|||
|
|
@ -123,7 +123,9 @@ static bool have_script_upload_cap(LLUUID& object_id)
|
|||
class LLLiveLSLFile : public LLLiveFile
|
||||
{
|
||||
public:
|
||||
LLLiveLSLFile(std::string file_path, LLLiveLSLEditor* parent);
|
||||
typedef boost::function<bool (const std::string& filename)> change_callback_t;
|
||||
|
||||
LLLiveLSLFile(std::string file_path, change_callback_t change_cb);
|
||||
~LLLiveLSLFile();
|
||||
|
||||
void ignoreNextUpdate() { mIgnoreNextUpdate = true; }
|
||||
|
|
@ -131,15 +133,16 @@ public:
|
|||
protected:
|
||||
/*virtual*/ bool loadFile();
|
||||
|
||||
LLLiveLSLEditor* mParent;
|
||||
change_callback_t mOnChangeCallback;
|
||||
bool mIgnoreNextUpdate;
|
||||
};
|
||||
|
||||
LLLiveLSLFile::LLLiveLSLFile(std::string file_path, LLLiveLSLEditor* parent)
|
||||
: mParent(parent)
|
||||
LLLiveLSLFile::LLLiveLSLFile(std::string file_path, change_callback_t change_cb)
|
||||
: mOnChangeCallback(change_cb)
|
||||
, mIgnoreNextUpdate(false)
|
||||
, LLLiveFile(file_path, 1.0)
|
||||
{
|
||||
llassert(mOnChangeCallback);
|
||||
}
|
||||
|
||||
LLLiveLSLFile::~LLLiveLSLFile()
|
||||
|
|
@ -155,14 +158,7 @@ bool LLLiveLSLFile::loadFile()
|
|||
return true;
|
||||
}
|
||||
|
||||
if (!mParent->loadScriptText(filename()))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Disable sync to avoid recursive load->save->load calls.
|
||||
mParent->saveIfNeeded(false);
|
||||
return true;
|
||||
return mOnChangeCallback(filename());
|
||||
}
|
||||
|
||||
/// ---------------------------------------------------------------------------
|
||||
|
|
@ -327,11 +323,11 @@ struct LLSECKeywordCompare
|
|||
};
|
||||
|
||||
LLScriptEdCore::LLScriptEdCore(
|
||||
LLScriptEdContainer* container,
|
||||
const std::string& sample,
|
||||
const LLHandle<LLFloater>& floater_handle,
|
||||
void (*load_callback)(void*),
|
||||
void (*save_callback)(void*, BOOL),
|
||||
void (*edit_callback)(void*),
|
||||
void (*search_replace_callback) (void* userdata),
|
||||
void* userdata,
|
||||
S32 bottom_pad)
|
||||
|
|
@ -341,19 +337,21 @@ LLScriptEdCore::LLScriptEdCore(
|
|||
mEditor( NULL ),
|
||||
mLoadCallback( load_callback ),
|
||||
mSaveCallback( save_callback ),
|
||||
mEditCallback( edit_callback ),
|
||||
mSearchReplaceCallback( search_replace_callback ),
|
||||
mUserdata( userdata ),
|
||||
mForceClose( FALSE ),
|
||||
mLastHelpToken(NULL),
|
||||
mLiveHelpHistorySize(0),
|
||||
mEnableSave(FALSE),
|
||||
mLiveFile(NULL),
|
||||
mContainer(container),
|
||||
mHasScriptData(FALSE)
|
||||
{
|
||||
setFollowsAll();
|
||||
setBorderVisible(FALSE);
|
||||
|
||||
setXMLFilename("panel_script_ed.xml");
|
||||
llassert_always(mContainer != NULL);
|
||||
}
|
||||
|
||||
LLScriptEdCore::~LLScriptEdCore()
|
||||
|
|
@ -367,6 +365,8 @@ LLScriptEdCore::~LLScriptEdCore()
|
|||
script_search->closeFloater();
|
||||
delete script_search;
|
||||
}
|
||||
|
||||
delete mLiveFile;
|
||||
}
|
||||
|
||||
BOOL LLScriptEdCore::postBuild()
|
||||
|
|
@ -381,7 +381,7 @@ BOOL LLScriptEdCore::postBuild()
|
|||
|
||||
childSetCommitCallback("lsl errors", &LLScriptEdCore::onErrorList, this);
|
||||
childSetAction("Save_btn", boost::bind(&LLScriptEdCore::doSave,this,FALSE));
|
||||
childSetAction("Edit_btn", boost::bind(&LLScriptEdCore::onEditButtonClick, this));
|
||||
childSetAction("Edit_btn", boost::bind(&LLScriptEdCore::openInExternalEditor, this));
|
||||
|
||||
initMenu();
|
||||
|
||||
|
|
@ -514,6 +514,79 @@ void LLScriptEdCore::setScriptText(const std::string& text, BOOL is_valid)
|
|||
}
|
||||
}
|
||||
|
||||
bool LLScriptEdCore::loadScriptText(const std::string& filename)
|
||||
{
|
||||
if (filename.empty())
|
||||
{
|
||||
llwarns << "Empty file name" << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
|
||||
if (!file)
|
||||
{
|
||||
llwarns << "Error opening " << filename << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// read in the whole file
|
||||
fseek(file, 0L, SEEK_END);
|
||||
size_t file_length = (size_t) 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 < file_length)
|
||||
{
|
||||
llwarns << "Short read" << llendl;
|
||||
}
|
||||
buffer[nread] = '\0';
|
||||
fclose(file);
|
||||
|
||||
mEditor->setText(LLStringExplicit(buffer));
|
||||
delete[] buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLScriptEdCore::writeToFile(const std::string& filename)
|
||||
{
|
||||
LLFILE* fp = LLFile::fopen(filename, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
llwarns << "Unable to write to " << filename << llendl;
|
||||
|
||||
LLSD row;
|
||||
row["columns"][0]["value"] = "Error writing to local file. Is your hard drive full?";
|
||||
row["columns"][0]["font"] = "SANSSERIF_SMALL";
|
||||
mErrorList->addElement(row);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string utf8text = 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);
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLScriptEdCore::sync()
|
||||
{
|
||||
// Sync with external editor.
|
||||
std::string tmp_file = mContainer->getTmpFileName();
|
||||
llstat s;
|
||||
if (LLFile::stat(tmp_file, &s) == 0) // file exists
|
||||
{
|
||||
if (mLiveFile) mLiveFile->ignoreNextUpdate();
|
||||
writeToFile(tmp_file);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLScriptEdCore::hasChanged()
|
||||
{
|
||||
if (!mEditor) return false;
|
||||
|
|
@ -690,6 +763,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);
|
||||
|
|
@ -862,11 +941,31 @@ void LLScriptEdCore::doSave( BOOL close_after_save )
|
|||
}
|
||||
}
|
||||
|
||||
void LLScriptEdCore::onEditButtonClick()
|
||||
void LLScriptEdCore::openInExternalEditor()
|
||||
{
|
||||
if (mEditCallback)
|
||||
delete mLiveFile; // deletes file
|
||||
|
||||
// Save the script to a temporary file.
|
||||
std::string filename = mContainer->getTmpFileName();
|
||||
writeToFile(filename);
|
||||
|
||||
// Start watching file changes.
|
||||
mLiveFile = new LLLiveLSLFile(filename, boost::bind(&LLScriptEdContainer::onExternalChange, mContainer, _1));
|
||||
mLiveFile->addToEventTimer();
|
||||
|
||||
// Open it in external editor.
|
||||
{
|
||||
mEditCallback(mUserdata);
|
||||
LLExternalEditor ed;
|
||||
|
||||
if (!ed.setCommand("LL_SCRIPT_EDITOR"))
|
||||
{
|
||||
std::string msg = "Select an editor by setting the environment variable LL_SCRIPT_EDITOR "
|
||||
"or the ExternalEditor setting"; // *TODO: localize
|
||||
LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
|
||||
return;
|
||||
}
|
||||
|
||||
ed.run(filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -982,6 +1081,43 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/// ---------------------------------------------------------------------------
|
||||
/// LLScriptEdContainer
|
||||
/// ---------------------------------------------------------------------------
|
||||
|
||||
LLScriptEdContainer::LLScriptEdContainer(const LLSD& key)
|
||||
: LLPreview(key)
|
||||
, 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;
|
||||
}
|
||||
|
||||
/// ---------------------------------------------------------------------------
|
||||
/// LLPreviewLSL
|
||||
/// ---------------------------------------------------------------------------
|
||||
|
|
@ -1005,11 +1141,11 @@ void* LLPreviewLSL::createScriptEdPanel(void* userdata)
|
|||
LLPreviewLSL *self = (LLPreviewLSL*)userdata;
|
||||
|
||||
self->mScriptEd = new LLScriptEdCore(
|
||||
self,
|
||||
HELLO_LSL,
|
||||
self->getHandle(),
|
||||
LLPreviewLSL::onLoad,
|
||||
LLPreviewLSL::onSave,
|
||||
NULL, // no edit callback
|
||||
LLPreviewLSL::onSearchReplace,
|
||||
self,
|
||||
0);
|
||||
|
|
@ -1019,7 +1155,7 @@ void* LLPreviewLSL::createScriptEdPanel(void* userdata)
|
|||
|
||||
|
||||
LLPreviewLSL::LLPreviewLSL(const LLSD& key )
|
||||
: LLPreview( key ),
|
||||
: LLScriptEdContainer(key),
|
||||
mPendingUploads(0)
|
||||
{
|
||||
mFactoryMap["script panel"] = LLCallbackMap(LLPreviewLSL::createScriptEdPanel, this);
|
||||
|
|
@ -1110,7 +1246,6 @@ 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;
|
||||
}
|
||||
|
|
@ -1120,6 +1255,7 @@ void LLPreviewLSL::loadAsset()
|
|||
else
|
||||
{
|
||||
mScriptEd->setScriptText(std::string(HELLO_LSL), TRUE);
|
||||
mScriptEd->setEnableEditing(TRUE);
|
||||
mAssetStatus = PREVIEW_ASSET_LOADED;
|
||||
}
|
||||
}
|
||||
|
|
@ -1166,7 +1302,7 @@ 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(!mScriptEd->hasChanged())
|
||||
|
|
@ -1185,23 +1321,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;
|
||||
|
||||
LLSD row;
|
||||
row["columns"][0]["value"] = "Error writing to local file. Is your hard drive full?";
|
||||
row["columns"][0]["font"] = "SANSSERIF_SMALL";
|
||||
mScriptEd->mErrorList->addElement(row);
|
||||
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");
|
||||
|
|
@ -1433,7 +1559,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
|
||||
|
|
@ -1474,11 +1600,11 @@ void* LLLiveLSLEditor::createScriptEdPanel(void* userdata)
|
|||
LLLiveLSLEditor *self = (LLLiveLSLEditor*)userdata;
|
||||
|
||||
self->mScriptEd = new LLScriptEdCore(
|
||||
self,
|
||||
HELLO_LSL,
|
||||
self->getHandle(),
|
||||
&LLLiveLSLEditor::onLoad,
|
||||
&LLLiveLSLEditor::onSave,
|
||||
&LLLiveLSLEditor::onEdit,
|
||||
&LLLiveLSLEditor::onSearchReplace,
|
||||
self,
|
||||
0);
|
||||
|
|
@ -1488,14 +1614,12 @@ void* LLLiveLSLEditor::createScriptEdPanel(void* userdata)
|
|||
|
||||
|
||||
LLLiveLSLEditor::LLLiveLSLEditor(const LLSD& key) :
|
||||
LLPreview(key),
|
||||
mScriptEd(NULL),
|
||||
LLScriptEdContainer(key),
|
||||
mAskedForRunningInfo(FALSE),
|
||||
mHaveRunningInfo(FALSE),
|
||||
mCloseAfterSave(FALSE),
|
||||
mPendingUploads(0),
|
||||
mIsModifiable(FALSE),
|
||||
mLiveFile(NULL),
|
||||
mIsNew(false)
|
||||
{
|
||||
mFactoryMap["script ed panel"] = LLCallbackMap(LLLiveLSLEditor::createScriptEdPanel, this);
|
||||
|
|
@ -1519,11 +1643,6 @@ BOOL LLLiveLSLEditor::postBuild()
|
|||
return LLPreview::postBuild();
|
||||
}
|
||||
|
||||
LLLiveLSLEditor::~LLLiveLSLEditor()
|
||||
{
|
||||
delete mLiveFile;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void LLLiveLSLEditor::callbackLSLCompileSucceeded(const LLUUID& task_id,
|
||||
const LLUUID& item_id,
|
||||
|
|
@ -1580,7 +1699,6 @@ void LLLiveLSLEditor::loadAsset()
|
|||
mItem = new LLViewerInventoryItem(item);
|
||||
mScriptEd->setScriptText(getString("not_allowed"), FALSE);
|
||||
mScriptEd->mEditor->makePristine();
|
||||
mScriptEd->mEditor->setEnabled(FALSE);
|
||||
mScriptEd->enableSave(FALSE);
|
||||
mAssetStatus = PREVIEW_ASSET_LOADED;
|
||||
}
|
||||
|
|
@ -1618,10 +1736,6 @@ void LLLiveLSLEditor::loadAsset()
|
|||
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.
|
||||
|
|
@ -1677,6 +1791,7 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id,
|
|||
if( LL_ERR_NOERR == status )
|
||||
{
|
||||
instance->loadScriptText(vfs, asset_id, type);
|
||||
instance->mScriptEd->setEnableEditing(TRUE);
|
||||
instance->mAssetStatus = PREVIEW_ASSET_LOADED;
|
||||
}
|
||||
else
|
||||
|
|
@ -1703,40 +1818,6 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id,
|
|||
delete xored_id;
|
||||
}
|
||||
|
||||
bool LLLiveLSLEditor::loadScriptText(const std::string& filename)
|
||||
{
|
||||
if (filename.empty())
|
||||
{
|
||||
llwarns << "Empty file name" << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
LLFILE* file = LLFile::fopen(filename, "rb"); /*Flawfinder: ignore*/
|
||||
if (!file)
|
||||
{
|
||||
llwarns << "Error opening " << filename << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// read in the whole file
|
||||
fseek(file, 0L, SEEK_END);
|
||||
size_t file_length = (size_t) 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 < file_length)
|
||||
{
|
||||
llwarns << "Short read" << llendl;
|
||||
}
|
||||
buffer[nread] = '\0';
|
||||
fclose(file);
|
||||
mScriptEd->mEditor->setText(LLStringExplicit(buffer));
|
||||
//mScriptEd->mEditor->makePristine();
|
||||
delete[] buffer;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLLiveLSLEditor::loadScriptText(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type)
|
||||
{
|
||||
LLVFile file(vfs, uuid, type);
|
||||
|
|
@ -1890,7 +1971,8 @@ LLLiveLSLSaveData::LLLiveLSLSaveData(const LLUUID& id,
|
|||
mItem = new LLViewerInventoryItem(item);
|
||||
}
|
||||
|
||||
void LLLiveLSLEditor::saveIfNeeded(bool sync)
|
||||
// virtual
|
||||
void LLLiveLSLEditor::saveIfNeeded(bool sync /*= true*/)
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(mObjectUUID);
|
||||
if(!object)
|
||||
|
|
@ -1941,18 +2023,11 @@ void LLLiveLSLEditor::saveIfNeeded(bool sync)
|
|||
mItem->setAssetUUID(asset_id);
|
||||
mItem->setTransactionID(tid);
|
||||
|
||||
writeToFile(filename);
|
||||
mScriptEd->writeToFile(filename);
|
||||
|
||||
if (sync)
|
||||
{
|
||||
// Sync with external ed2itor.
|
||||
std::string tmp_file = getTmpFileName();
|
||||
llstat s;
|
||||
if (LLFile::stat(tmp_file, &s) == 0) // file exists
|
||||
{
|
||||
if (mLiveFile) mLiveFile->ignoreNextUpdate();
|
||||
writeToFile(tmp_file);
|
||||
}
|
||||
mScriptEd->sync();
|
||||
}
|
||||
|
||||
// save it out to asset server
|
||||
|
|
@ -1970,83 +2045,6 @@ void LLLiveLSLEditor::saveIfNeeded(bool sync)
|
|||
}
|
||||
}
|
||||
|
||||
void LLLiveLSLEditor::openExternalEditor()
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(mObjectUUID);
|
||||
if(!object)
|
||||
{
|
||||
LLNotificationsUtil::add("SaveScriptFailObjectNotFound");
|
||||
return;
|
||||
}
|
||||
|
||||
delete mLiveFile; // deletes file
|
||||
|
||||
// Save the script to a temporary file.
|
||||
std::string filename = getTmpFileName();
|
||||
writeToFile(filename);
|
||||
|
||||
// Start watching file changes.
|
||||
mLiveFile = new LLLiveLSLFile(filename, this);
|
||||
mLiveFile->addToEventTimer();
|
||||
|
||||
// Open it in external editor.
|
||||
{
|
||||
LLExternalEditor ed;
|
||||
|
||||
if (!ed.setCommand("LL_SCRIPT_EDITOR"))
|
||||
{
|
||||
std::string msg = "Select an editor by setting the environment variable LL_SCRIPT_EDITOR "
|
||||
"or the ExternalEditor setting"; // *TODO: localize
|
||||
LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
|
||||
return;
|
||||
}
|
||||
|
||||
ed.run(filename);
|
||||
}
|
||||
}
|
||||
|
||||
bool LLLiveLSLEditor::writeToFile(const std::string& filename)
|
||||
{
|
||||
LLFILE* fp = LLFile::fopen(filename, "wb");
|
||||
if (!fp)
|
||||
{
|
||||
llwarns << "Unable to write to " << filename << llendl;
|
||||
|
||||
LLSD row;
|
||||
row["columns"][0]["value"] = "Error writing to local file. Is your hard drive full?";
|
||||
row["columns"][0]["font"] = "SANSSERIF_SMALL";
|
||||
mScriptEd->mErrorList->addElement(row);
|
||||
return false;
|
||||
}
|
||||
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string LLLiveLSLEditor::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";
|
||||
}
|
||||
|
||||
void LLLiveLSLEditor::uploadAssetViaCaps(const std::string& url,
|
||||
const std::string& filename,
|
||||
const LLUUID& task_id,
|
||||
|
|
@ -2270,13 +2268,6 @@ void LLLiveLSLEditor::onSave(void* userdata, BOOL close_after_save)
|
|||
}
|
||||
|
||||
|
||||
// static
|
||||
void LLLiveLSLEditor::onEdit(void* userdata)
|
||||
{
|
||||
LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata;
|
||||
self->openExternalEditor();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ class LLFloaterScriptSearch;
|
|||
class LLKeywordToken;
|
||||
class LLVFS;
|
||||
class LLViewerInventoryItem;
|
||||
class LLScriptEdContainer;
|
||||
|
||||
// Inner, implementation class. LLPreviewScript and LLLiveLSLEditor each own one of these.
|
||||
class LLScriptEdCore : public LLPanel
|
||||
|
|
@ -56,17 +57,20 @@ class LLScriptEdCore : public LLPanel
|
|||
friend class LLPreviewLSL;
|
||||
friend class LLLiveLSLEditor;
|
||||
friend class LLFloaterScriptSearch;
|
||||
friend class LLScriptEdContainer;
|
||||
|
||||
public:
|
||||
protected:
|
||||
// Supposed to be invoked only by the container.
|
||||
LLScriptEdCore(
|
||||
LLScriptEdContainer* container,
|
||||
const std::string& sample,
|
||||
const LLHandle<LLFloater>& floater_handle,
|
||||
void (*load_callback)(void* userdata),
|
||||
void (*save_callback)(void* userdata, BOOL close_after_save),
|
||||
void (*edit_callback)(void*),
|
||||
void (*search_replace_callback)(void* userdata),
|
||||
void* userdata,
|
||||
S32 bottom_pad = 0); // pad below bottom row of buttons
|
||||
public:
|
||||
~LLScriptEdCore();
|
||||
|
||||
void initMenu();
|
||||
|
|
@ -74,15 +78,19 @@ public:
|
|||
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();
|
||||
|
||||
void doSave( BOOL close_after_save );
|
||||
|
||||
bool handleSaveChangesDialog(const LLSD& notification, const LLSD& response);
|
||||
bool handleReloadFromServerDialog(const LLSD& notification, const LLSD& response);
|
||||
|
||||
void onEditButtonClick();
|
||||
void openInExternalEditor();
|
||||
|
||||
static void onCheckLock(LLUICtrl*, void*);
|
||||
static void onHelpComboCommit(LLUICtrl* ctrl, void* userdata);
|
||||
|
|
@ -118,7 +126,6 @@ private:
|
|||
LLTextEditor* mEditor;
|
||||
void (*mLoadCallback)(void* userdata);
|
||||
void (*mSaveCallback)(void* userdata, BOOL close_after_save);
|
||||
void (*mEditCallback)(void* userdata);
|
||||
void (*mSearchReplaceCallback) (void* userdata);
|
||||
void* mUserdata;
|
||||
LLComboBox *mFunctions;
|
||||
|
|
@ -132,11 +139,28 @@ private:
|
|||
S32 mLiveHelpHistorySize;
|
||||
BOOL mEnableSave;
|
||||
BOOL mHasScriptData;
|
||||
LLLiveLSLFile* mLiveFile;
|
||||
|
||||
LLScriptEdContainer* mContainer; // parent view
|
||||
};
|
||||
|
||||
class LLScriptEdContainer : public LLPreview
|
||||
{
|
||||
friend class LLScriptEdCore;
|
||||
|
||||
public:
|
||||
LLScriptEdContainer(const LLSD& key);
|
||||
|
||||
protected:
|
||||
std::string getTmpFileName();
|
||||
bool onExternalChange(const std::string& filename);
|
||||
virtual void saveIfNeeded(bool sync = true) = 0;
|
||||
|
||||
LLScriptEdCore* mScriptEd;
|
||||
};
|
||||
|
||||
// Used to view and edit a LSL from your inventory.
|
||||
class LLPreviewLSL : public LLPreview
|
||||
class LLPreviewLSL : public LLScriptEdContainer
|
||||
{
|
||||
public:
|
||||
LLPreviewLSL(const LLSD& key );
|
||||
|
|
@ -150,7 +174,7 @@ protected:
|
|||
void closeIfNeeded();
|
||||
|
||||
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);
|
||||
|
|
@ -174,7 +198,6 @@ protected:
|
|||
|
||||
protected:
|
||||
|
||||
LLScriptEdCore* mScriptEd;
|
||||
// Can safely close only after both text and bytecode are uploaded
|
||||
S32 mPendingUploads;
|
||||
|
||||
|
|
@ -182,12 +205,11 @@ 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 LLSD& key);
|
||||
~LLLiveLSLEditor();
|
||||
|
||||
|
||||
static void processScriptRunningReply(LLMessageSystem* msg, void**);
|
||||
|
|
@ -208,10 +230,7 @@ private:
|
|||
|
||||
virtual void loadAsset();
|
||||
void loadAsset(BOOL is_new);
|
||||
void saveIfNeeded(bool sync = true);
|
||||
void openExternalEditor();
|
||||
std::string getTmpFileName();
|
||||
bool writeToFile(const std::string& filename);
|
||||
/*virtual*/ void saveIfNeeded(bool sync = true);
|
||||
void uploadAssetViaCaps(const std::string& url,
|
||||
const std::string& filename,
|
||||
const LLUUID& task_id,
|
||||
|
|
@ -227,7 +246,6 @@ private:
|
|||
static void onSearchReplace(void* userdata);
|
||||
static void onLoad(void* userdata);
|
||||
static void onSave(void* userdata, BOOL close_after_save);
|
||||
static void onEdit(void* userdata);
|
||||
|
||||
static void onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
|
|
@ -237,7 +255,6 @@ private:
|
|||
static void onRunningCheckboxClicked(LLUICtrl*, void* userdata);
|
||||
static void onReset(void* userdata);
|
||||
|
||||
bool loadScriptText(const std::string& filename);
|
||||
void loadScriptText(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type);
|
||||
|
||||
static void onErrorList(LLUICtrl*, void* user_data);
|
||||
|
|
@ -248,7 +265,6 @@ private:
|
|||
|
||||
private:
|
||||
bool mIsNew;
|
||||
LLScriptEdCore* mScriptEd;
|
||||
//LLUUID mTransmitID;
|
||||
LLCheckBoxCtrl* mRunningCheckbox;
|
||||
BOOL mAskedForRunningInfo;
|
||||
|
|
@ -263,7 +279,6 @@ private:
|
|||
|
||||
LLCheckBoxCtrl* mMonoCheckbox;
|
||||
BOOL mIsModifiable;
|
||||
LLLiveLSLFile* mLiveFile;
|
||||
};
|
||||
|
||||
#endif // LL_LLPREVIEWSCRIPT_H
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@
|
|||
name="Save_btn"
|
||||
width="81" />
|
||||
<button
|
||||
enabled="false"
|
||||
follows="right|bottom"
|
||||
height="23"
|
||||
label="Edit..."
|
||||
|
|
|
|||
Loading…
Reference in New Issue