Export improvements:
FIRE-9625 - Make Import Linkset work like the other uploaders FIRE-11646 - Option to not backup object contents Combined permission checks into a single namespace Added object export floater for a more consistent workflow with collada export
parent
a0a69a72b5
commit
5c0e632ad5
|
|
@ -131,8 +131,9 @@ set(viewer_SOURCE_FILES
|
|||
fsconsoleutils.cpp
|
||||
fscontactsfloater.cpp
|
||||
fsdata.cpp
|
||||
fsexport.cpp
|
||||
fsexportperms.cpp
|
||||
fsfloaterblocklist.cpp
|
||||
fsfloaterexport.cpp
|
||||
fsfloatergroup.cpp
|
||||
fsfloatergrouptitles.cpp
|
||||
fsfloaterimport.cpp
|
||||
|
|
@ -819,8 +820,9 @@ set(viewer_HEADER_FILES
|
|||
fsconsoleutils.h
|
||||
fscontactsfloater.h
|
||||
fsdata.h
|
||||
fsexport.h
|
||||
fsexportperms.h
|
||||
fsfloaterblocklist.h
|
||||
fsfloaterexport.h
|
||||
fsfloatergroup.h
|
||||
fsfloatergrouptitles.h
|
||||
fsfloaterimport.h
|
||||
|
|
|
|||
|
|
@ -20877,7 +20877,7 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<key>FSBuildPrefs_Temporary</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>New object created default of tempary</string>
|
||||
<string>New object created default of temporary</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
|
|
@ -21443,5 +21443,16 @@ Change of this parameter will affect the layout of buttons in notification toast
|
|||
<integer>1.0</integer>
|
||||
</map>
|
||||
<!-- </FS:Zi> Fix camera zoom to look at the avatar's face from the front -->
|
||||
<key>FSExportContents</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string>Export object contents in linkset backups</string>
|
||||
<key>Persist</key>
|
||||
<integer>1</integer>
|
||||
<key>Type</key>
|
||||
<string>Boolean</string>
|
||||
<key>Value</key>
|
||||
<integer>1</integer>
|
||||
</map>
|
||||
</map>
|
||||
</llsd>
|
||||
|
|
|
|||
|
|
@ -74,9 +74,6 @@
|
|||
#include "llagent.h"
|
||||
#include "llcallbacklist.h"
|
||||
#include "llfilepicker.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llmeshrepository.h"
|
||||
#include "llnotificationsutil.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "lltexturecache.h"
|
||||
|
|
@ -86,6 +83,7 @@
|
|||
#include "llviewernetwork.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llvovolume.h"
|
||||
#include "fsexportperms.h"
|
||||
|
||||
static const F32 TEXTURE_DOWNLOAD_TIMEOUT = 60.f;
|
||||
|
||||
|
|
@ -105,178 +103,6 @@ namespace DAEExportUtil
|
|||
ft_png,
|
||||
ft_j2c
|
||||
};
|
||||
|
||||
static bool canExportTexture(const LLUUID& asset_id, std::string* name = NULL)
|
||||
{
|
||||
bool exportable = false;
|
||||
|
||||
LLViewerInventoryCategory::cat_array_t cats;
|
||||
LLViewerInventoryItem::item_array_t items;
|
||||
LLAssetIDMatches asset_id_matches(asset_id);
|
||||
gInventory.collectDescendentsIf(LLUUID::null,
|
||||
cats,
|
||||
items,
|
||||
LLInventoryModel::INCLUDE_TRASH,
|
||||
asset_id_matches);
|
||||
|
||||
for (S32 i = 0; i < items.count(); i++)
|
||||
{
|
||||
const LLPermissions perms = items[i]->getPermissions();
|
||||
if (LLGridManager::getInstance()->isInSecondLife())
|
||||
{
|
||||
exportable = (perms.getCreator() == gAgentID);
|
||||
}
|
||||
#ifdef OPENSIM
|
||||
else if (LLGridManager::getInstance()->isInOpenSim())
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (!region)
|
||||
{
|
||||
LL_WARNS("export") << "No region found to check export caps!" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
if (region->regionSupportsExport() == LLViewerRegion::EXPORT_ALLOWED)
|
||||
{
|
||||
exportable = (perms.getMaskOwner() & PERM_EXPORT) == PERM_EXPORT;
|
||||
}
|
||||
else if (region->regionSupportsExport() == LLViewerRegion::EXPORT_DENIED)
|
||||
{
|
||||
exportable = perms.getCreator() == gAgentID;
|
||||
}
|
||||
/// TODO: Once enough grids adopt a version supporting the exports cap, get consensus
|
||||
/// on whether we should allow full perm exports anymore.
|
||||
else
|
||||
{
|
||||
exportable = (perms.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED;
|
||||
}
|
||||
if (!exportable)
|
||||
LL_INFOS("export") << "Texture has failed permissions check." << LL_ENDL;
|
||||
}
|
||||
#endif
|
||||
if (exportable && name != NULL)
|
||||
(*name) = items[i]->getName();
|
||||
else if (name != NULL)
|
||||
(*name) = asset_id.getString();
|
||||
}
|
||||
return exportable;
|
||||
}
|
||||
|
||||
static bool canExportNode(LLSelectNode* node)
|
||||
{
|
||||
bool exportable = false;
|
||||
|
||||
LLViewerObject* object = node->getObject();
|
||||
if (LLGridManager::getInstance()->isInSecondLife())
|
||||
{
|
||||
exportable = (object->permYouOwner()
|
||||
&& gAgentID == node->mPermissions->getCreator());
|
||||
}
|
||||
#ifdef OPENSIM
|
||||
else if (LLGridManager::getInstance()->isInOpenSim())
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region && region->regionSupportsExport() == LLViewerRegion::EXPORT_ALLOWED)
|
||||
{
|
||||
exportable = node->mPermissions->allowExportBy(gAgent.getID());
|
||||
}
|
||||
else if (region && region->regionSupportsExport() == LLViewerRegion::EXPORT_DENIED)
|
||||
{
|
||||
// Only your own creations if this is explicitly set
|
||||
exportable = (object->permYouOwner()
|
||||
&& gAgentID == node->mPermissions->getCreator());
|
||||
}
|
||||
/// TODO: Once enough grids adopt a version supporting the exports cap, get consensus
|
||||
/// on whether we should allow full perm exports anymore.
|
||||
else // LLViewerRegion::EXPORT_UNDEFINED
|
||||
{
|
||||
exportable = (object->permYouOwner()
|
||||
&& object->permModify()
|
||||
&& object->permCopy()
|
||||
&& object->permTransfer());
|
||||
}
|
||||
}
|
||||
#endif // OPENSIM
|
||||
// We've got perms on the object itself, let's check for sculptmaps and meshes!
|
||||
if (exportable)
|
||||
{
|
||||
LLVOVolume *volobjp = NULL;
|
||||
if (object->getPCode() == LL_PCODE_VOLUME)
|
||||
{
|
||||
volobjp = (LLVOVolume *)object;
|
||||
}
|
||||
if (volobjp && volobjp->isSculpted())
|
||||
{
|
||||
const LLSculptParams *sculpt_params = (const LLSculptParams *)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
|
||||
if (LLGridManager::getInstance()->isInSecondLife())
|
||||
{
|
||||
if(volobjp->isMesh())
|
||||
{
|
||||
LLSD mesh_header = gMeshRepo.getMeshHeader(sculpt_params->getSculptTexture());
|
||||
exportable = mesh_header["creator"].asUUID() == gAgentID;
|
||||
}
|
||||
else if (sculpt_params)
|
||||
{
|
||||
LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(sculpt_params->getSculptTexture());
|
||||
exportable = (imagep->mComment.find("a") != imagep->mComment.end()
|
||||
&& LLUUID(imagep->mComment["a"]) == gAgentID);
|
||||
if (!exportable)
|
||||
LL_INFOS("export") << "Sculpt map has failed permissions check." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
#ifdef OPENSIM
|
||||
else if (LLGridManager::getInstance()->isInOpenSim())
|
||||
{
|
||||
if (sculpt_params && !volobjp->isMesh())
|
||||
{
|
||||
LLUUID asset_id = sculpt_params->getSculptTexture();
|
||||
LLViewerInventoryCategory::cat_array_t cats;
|
||||
LLViewerInventoryItem::item_array_t items;
|
||||
LLAssetIDMatches asset_id_matches(asset_id);
|
||||
gInventory.collectDescendentsIf(LLUUID::null, cats, items,
|
||||
LLInventoryModel::INCLUDE_TRASH,
|
||||
asset_id_matches);
|
||||
|
||||
for (S32 i = 0; i < items.count(); ++i)
|
||||
{
|
||||
const LLPermissions perms = items[i]->getPermissions();
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (!region)
|
||||
{
|
||||
LL_WARNS("export") << "No region found to check export caps!" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
if (region->regionSupportsExport() == LLViewerRegion::EXPORT_ALLOWED)
|
||||
{
|
||||
exportable = (perms.getMaskOwner() & PERM_EXPORT) == PERM_EXPORT;
|
||||
}
|
||||
else if (region->regionSupportsExport() == LLViewerRegion::EXPORT_DENIED)
|
||||
{
|
||||
exportable = perms.getCreator() == gAgentID;
|
||||
}
|
||||
/// TODO: Once enough grids adopt a version supporting the exports cap, get consensus
|
||||
/// on whether we should allow full perm exports anymore.
|
||||
else
|
||||
{
|
||||
exportable = (perms.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED;
|
||||
}
|
||||
if (!exportable)
|
||||
LL_INFOS("export") << "Sculpt map has failed permissions check." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
exportable = true;
|
||||
}
|
||||
}
|
||||
#endif // OPENSIM
|
||||
}
|
||||
else
|
||||
{
|
||||
exportable = true;
|
||||
}
|
||||
}
|
||||
return exportable;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -384,14 +210,14 @@ void ColladaExportFloater::addSelectedObjects()
|
|||
{
|
||||
mTotal++;
|
||||
LLSelectNode* node = *iter;
|
||||
if (!node->getObject()->getVolume() || !DAEExportUtil::canExportNode(node)) continue;
|
||||
if (!node->getObject()->getVolume() || !FSExportPermsCheck::canExportNode(node)) continue;
|
||||
mIncluded++;
|
||||
mSaver.add(node->getObject(), node->mName);
|
||||
}
|
||||
|
||||
if (mSaver.mObjects.empty())
|
||||
{
|
||||
LLNotificationsUtil::add("ExportColladaFailed");
|
||||
LLNotificationsUtil::add("ExportFailed");
|
||||
closeFloater();
|
||||
return;
|
||||
}
|
||||
|
|
@ -641,9 +467,27 @@ void DAESaver::updateTextureInfo()
|
|||
if (std::find(mTextures.begin(), mTextures.end(), id) != mTextures.end()) continue;
|
||||
|
||||
mTextures.push_back(id);
|
||||
bool exportable = false;
|
||||
LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id);
|
||||
std::string name;
|
||||
if (id != DAEExportUtil::LL_TEXTURE_BLANK
|
||||
&& DAEExportUtil::canExportTexture(id, &name))
|
||||
std::string description;
|
||||
if (LLGridManager::getInstance()->isInSecondLife())
|
||||
{
|
||||
if (imagep->mComment.find("a") != imagep->mComment.end())
|
||||
{
|
||||
if (LLUUID(imagep->mComment["a"]) == gAgentID)
|
||||
{
|
||||
exportable = true;
|
||||
LL_DEBUGS("export") << id << " passed texture export comment check." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (exportable)
|
||||
FSExportPermsCheck::canExportAsset(id, &name, &description);
|
||||
else
|
||||
exportable = FSExportPermsCheck::canExportAsset(id, &name, &description);
|
||||
|
||||
if (id != DAEExportUtil::LL_TEXTURE_BLANK && exportable)
|
||||
{
|
||||
std::string safe_name = gDirUtilp->getScrubbedFileName(name);
|
||||
std::replace(safe_name.begin(), safe_name.end(), ' ', '_');
|
||||
|
|
|
|||
|
|
@ -127,7 +127,6 @@ private:
|
|||
virtual ~ColladaExportFloater();
|
||||
void onClickExport();
|
||||
void onTextureExportCheck();
|
||||
void filepickerCallback();
|
||||
void onCommitTextureType();
|
||||
void saveTextures();
|
||||
void addSelectedObjects();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* @file fsexportperms.cpp
|
||||
* @brief Export permissions check
|
||||
* @authors Cinder Biscuits
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=LGPLV2.1$
|
||||
* Copyright (C) 2013 Cinder Biscuits <cinder.roxley@phoenixviewer.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write a love letter
|
||||
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "fsexportperms.h"
|
||||
#include "llagent.h"
|
||||
#include "llinventoryfunctions.h"
|
||||
#include "llmeshrepository.h"
|
||||
#include "llviewernetwork.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llvovolume.h"
|
||||
#include "llworld.h"
|
||||
|
||||
#define FOLLOW_PERMS 1
|
||||
|
||||
bool FSExportPermsCheck::canExportNode(LLSelectNode* node)
|
||||
{
|
||||
if (!node)
|
||||
{
|
||||
LL_WARNS("export") << "No node, bailing!" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
bool exportable = false;
|
||||
|
||||
LLViewerObject* object = node->getObject();
|
||||
if (LLGridManager::getInstance()->isInSecondLife())
|
||||
{
|
||||
LLUUID creator(node->mPermissions->getCreator());
|
||||
exportable = (object->permYouOwner() && gAgentID == creator);
|
||||
if (!exportable)
|
||||
{
|
||||
// Megaprim check
|
||||
F32 max_object_size = LLWorld::getInstance()->getRegionMaxPrimScale();
|
||||
LLVector3 vec = object->getScale();
|
||||
exportable = (!(vec.mV[VX] > max_object_size || vec.mV[VY] > max_object_size || vec.mV[VZ] > max_object_size));
|
||||
exportable = (creator == LLUUID("7ffd02d0-12f4-48b4-9640-695708fd4ae4")); // Zwagoth Klaar
|
||||
}
|
||||
}
|
||||
#ifdef OPENSIM
|
||||
else if (LLGridManager::getInstance()->isInOpenSim())
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (region && region->regionSupportsExport() == LLViewerRegion::EXPORT_ALLOWED)
|
||||
{
|
||||
exportable = node->mPermissions->allowExportBy(gAgent.getID());
|
||||
}
|
||||
else if (region && region->regionSupportsExport() == LLViewerRegion::EXPORT_DENIED)
|
||||
{
|
||||
// Only your own creations if this is explicitly set
|
||||
exportable = (object->permYouOwner()
|
||||
&& gAgentID == node->mPermissions->getCreator());
|
||||
}
|
||||
/// TODO: Once enough grids adopt a version supporting the exports cap, get consensus
|
||||
/// on whether we should allow full perm exports anymore.
|
||||
else // LLViewerRegion::EXPORT_UNDEFINED
|
||||
{
|
||||
exportable = (object->permYouOwner()
|
||||
&& object->permModify()
|
||||
&& object->permCopy()
|
||||
&& object->permTransfer());
|
||||
}
|
||||
}
|
||||
#endif // OPENSIM
|
||||
// We've got perms on the object itself, let's check for sculptmaps and meshes!
|
||||
if (exportable)
|
||||
{
|
||||
LLVOVolume *volobjp = NULL;
|
||||
if (object->getPCode() == LL_PCODE_VOLUME)
|
||||
{
|
||||
volobjp = (LLVOVolume *)object;
|
||||
}
|
||||
if (volobjp && volobjp->isSculpted())
|
||||
{
|
||||
const LLSculptParams *sculpt_params = (const LLSculptParams *)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
|
||||
if (LLGridManager::getInstance()->isInSecondLife())
|
||||
{
|
||||
if(volobjp->isMesh())
|
||||
{
|
||||
LLSD mesh_header = gMeshRepo.getMeshHeader(sculpt_params->getSculptTexture());
|
||||
exportable = mesh_header["creator"].asUUID() == gAgentID;
|
||||
}
|
||||
else if (sculpt_params)
|
||||
{
|
||||
LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(sculpt_params->getSculptTexture());
|
||||
exportable = (imagep->mComment.find("a") != imagep->mComment.end()
|
||||
&& LLUUID(imagep->mComment["a"]) == gAgentID);
|
||||
if (!exportable)
|
||||
LL_INFOS("export") << "Sculpt map has failed permissions check." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
#ifdef OPENSIM
|
||||
else if (LLGridManager::getInstance()->isInOpenSim())
|
||||
{
|
||||
if (sculpt_params && !volobjp->isMesh())
|
||||
{
|
||||
LLUUID asset_id = sculpt_params->getSculptTexture();
|
||||
LLViewerInventoryCategory::cat_array_t cats;
|
||||
LLViewerInventoryItem::item_array_t items;
|
||||
LLAssetIDMatches asset_id_matches(asset_id);
|
||||
gInventory.collectDescendentsIf(LLUUID::null, cats, items,
|
||||
LLInventoryModel::INCLUDE_TRASH,
|
||||
asset_id_matches);
|
||||
|
||||
for (S32 i = 0; i < items.count(); ++i)
|
||||
{
|
||||
const LLPermissions perms = items[i]->getPermissions();
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (!region)
|
||||
{
|
||||
LL_WARNS("export") << "No region found to check export caps!" << LL_ENDL;
|
||||
return false;
|
||||
}
|
||||
if (region->regionSupportsExport() == LLViewerRegion::EXPORT_ALLOWED)
|
||||
{
|
||||
exportable = (perms.getMaskOwner() & PERM_EXPORT) == PERM_EXPORT;
|
||||
}
|
||||
else if (region->regionSupportsExport() == LLViewerRegion::EXPORT_DENIED)
|
||||
{
|
||||
exportable = perms.getCreator() == gAgentID;
|
||||
}
|
||||
/// TODO: Once enough grids adopt a version supporting the exports cap, get consensus
|
||||
/// on whether we should allow full perm exports anymore.
|
||||
else
|
||||
{
|
||||
exportable = (perms.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED;
|
||||
}
|
||||
if (!exportable)
|
||||
LL_INFOS("export") << "Sculpt map has failed permissions check." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
exportable = true;
|
||||
}
|
||||
}
|
||||
#endif // OPENSIM
|
||||
}
|
||||
else
|
||||
{
|
||||
exportable = true;
|
||||
}
|
||||
}
|
||||
return exportable;
|
||||
}
|
||||
|
||||
#if !FOLLOW_PERMS
|
||||
You didn't think it would be that easy did you? :P
|
||||
#endif
|
||||
|
||||
bool FSExportPermsCheck::canExportAsset(LLUUID asset_id, std::string* name, std::string* description)
|
||||
{
|
||||
bool exportable = false;
|
||||
LLViewerInventoryCategory::cat_array_t cats;
|
||||
LLViewerInventoryItem::item_array_t items;
|
||||
LLAssetIDMatches asset_id_matches(asset_id);
|
||||
gInventory.collectDescendentsIf(LLUUID::null,
|
||||
cats,
|
||||
items,
|
||||
LLInventoryModel::INCLUDE_TRASH,
|
||||
asset_id_matches);
|
||||
|
||||
if (items.count())
|
||||
{
|
||||
// use the name of the first match
|
||||
(*name) = items[0]->getName();
|
||||
(*description) = items[0]->getDescription();
|
||||
|
||||
for (S32 i = 0; i < items.count(); ++i)
|
||||
{
|
||||
if (!exportable)
|
||||
{
|
||||
LLPermissions perms = items[i]->getPermissions();
|
||||
#ifdef OPENSIM
|
||||
if (LLGridManager::getInstance()->isInOpenSim())
|
||||
{
|
||||
LLViewerRegion* region = gAgent.getRegion();
|
||||
if (!region) return false;
|
||||
if (region->regionSupportsExport() == LLViewerRegion::EXPORT_ALLOWED)
|
||||
{
|
||||
exportable = (perms.getMaskOwner() & PERM_EXPORT) == PERM_EXPORT;
|
||||
}
|
||||
else if (region->regionSupportsExport() == LLViewerRegion::EXPORT_DENIED)
|
||||
{
|
||||
exportable = perms.getCreator() == gAgentID;
|
||||
}
|
||||
/// TODO: Once enough grids adopt a version supporting the exports cap, get consensus
|
||||
/// on whether we should allow full perm exports anymore.
|
||||
else
|
||||
{
|
||||
exportable = (perms.getMaskBase() & PERM_ITEM_UNRESTRICTED) == PERM_ITEM_UNRESTRICTED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (LLGridManager::getInstance()->isInSecondLife() && (perms.getCreator() == gAgentID))
|
||||
{
|
||||
exportable = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return exportable;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* @file fsexportperms.h
|
||||
* @brief Export permissions check definitions
|
||||
* @authors Cinder Biscuits
|
||||
*
|
||||
* $LicenseInfo:firstyear=2013&license=LGPLV2.1$
|
||||
* Copyright (C) 2013 Cinder Biscuits <cinder.roxley@phoenixviewer.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General
|
||||
* Public License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef FS_EXPORTPERMS_H
|
||||
#define FS_EXPORTPERMS_H
|
||||
|
||||
#include "llselectmgr.h"
|
||||
|
||||
const S32 OXP_FORMAT_VERSION = 2;
|
||||
|
||||
namespace FSExportPermsCheck
|
||||
{
|
||||
bool canExportNode(LLSelectNode* node);
|
||||
bool canExportAsset(LLUUID asset_id, std::string* name = NULL, std::string* description = NULL);
|
||||
};
|
||||
|
||||
#endif // FS_EXPORTPERMS_H
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,10 +1,11 @@
|
|||
/**
|
||||
* @file fsexport.h
|
||||
* @file fsfloaterexport.h
|
||||
* @brief export selected objects to an xml file in LLSD format.
|
||||
*
|
||||
* $LicenseInfo:firstyear=2012&license=viewerlgpl$
|
||||
* Phoenix Firestorm Viewer Source Code
|
||||
* Copyright (c) 2012 Techwolf Lupindo
|
||||
* Copyright (c) 2013 Cinder Roxley <cinder.roxley@phoenixviewer.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
|
|
@ -45,92 +46,104 @@ struct FSAssetResourceData
|
|||
LLUUID uuid;
|
||||
};
|
||||
|
||||
class FSExport : public LLSingleton<FSExport>, public LLVOInventoryListener
|
||||
class FSFloaterObjectExport : public LLFloater, public LLVOInventoryListener
|
||||
{
|
||||
LOG_CLASS(FSExport);
|
||||
LOG_CLASS(FSFloaterObjectExport);
|
||||
public:
|
||||
void exportSelection();
|
||||
FSFloaterObjectExport(const LLSD& key);
|
||||
BOOL postBuild();
|
||||
|
||||
static void onImageLoaded(BOOL success,
|
||||
LLViewerFetchedTexture *src_vi,
|
||||
LLImageRaw* src,
|
||||
LLImageRaw* aux_src,
|
||||
S32 discard_level,
|
||||
BOOL final,
|
||||
void* userdata);
|
||||
LLViewerFetchedTexture *src_vi,
|
||||
LLImageRaw* src,
|
||||
LLImageRaw* aux_src,
|
||||
S32 discard_level,
|
||||
BOOL final,
|
||||
void* userdata);
|
||||
void fetchTextureFromCache(LLViewerFetchedTexture* src_vi);
|
||||
void saveFormattedImage(LLPointer<LLImageFormatted> mFormattedImage, LLUUID id);
|
||||
void removeRequestedTexture(LLUUID texture_id);
|
||||
static void onIdle(void *user_data);
|
||||
/*virtual*/ void inventoryChanged(LLViewerObject* object,
|
||||
LLInventoryObject::object_list_t* inventory,
|
||||
S32 serial_num,
|
||||
void* user_data);
|
||||
LLInventoryObject::object_list_t* inventory,
|
||||
S32 serial_num,
|
||||
void* user_data);
|
||||
static void onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid,
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
|
||||
LLAssetType::EType type,
|
||||
void* user_data, S32 status, LLExtStat ext_status);
|
||||
|
||||
private:
|
||||
typedef enum
|
||||
{
|
||||
IDLE,
|
||||
INVENTORY_DOWNLOAD,
|
||||
ASSET_DOWNLOAD,
|
||||
TEXTURE_DOWNLOAD
|
||||
} FSExportState;
|
||||
typedef enum {IDLE, INVENTORY_DOWNLOAD, ASSET_DOWNLOAD, TEXTURE_DOWNLOAD} FSExportState;
|
||||
virtual ~FSFloaterObjectExport();
|
||||
|
||||
bool exportSelection();
|
||||
void addSelectedObjects();
|
||||
void populateObjectList();
|
||||
void onClickExport();
|
||||
void addTexturePreview();
|
||||
S32 getNumExportableTextures();
|
||||
void addObject(const LLViewerObject* prim, const std::string name);
|
||||
void updateTextureInfo();
|
||||
void updateTitleProgress(FSExportState state);
|
||||
|
||||
FSExportState mExportState;
|
||||
|
||||
typedef std::vector<std::pair<LLViewerObject*,std::string> > obj_info_t;
|
||||
obj_info_t mObjects;
|
||||
std::string mFilename;
|
||||
LLObjectSelectionHandle mSelection;
|
||||
|
||||
S32 mTotal;
|
||||
S32 mIncluded;
|
||||
S32 mNumTextures;
|
||||
S32 mNumExportableTextures;
|
||||
|
||||
LLButton* mExportBtn;
|
||||
LLScrollListCtrl* mObjectList;
|
||||
LLScrollListCtrl* mTextureList;
|
||||
|
||||
std::string mObjectName;
|
||||
|
||||
LLSD getLinkSet(LLSelectNode* node);
|
||||
void addPrim(LLViewerObject* object, bool root);
|
||||
bool exportTexture(const LLUUID& texture_id);
|
||||
|
||||
|
||||
void onIdle();
|
||||
void removeRequestedAsset(LLUUID asset_uuid);
|
||||
bool assetCheck(LLUUID asset_id, std::string& name, std::string& description);
|
||||
bool megaPrimCheck(LLUUID creator, LLViewerObject* object);
|
||||
bool defaultTextureCheck(const LLUUID asset_id);
|
||||
|
||||
LLSD mFile;
|
||||
LLSD mManifest;
|
||||
std::map<LLUUID, FSAssetResourceData> mRequestedTexture;
|
||||
std::string mFileName;
|
||||
std::map<LLUUID, bool> mTextureChecked;
|
||||
std::string mFilePath;
|
||||
LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList;
|
||||
LLFrameTimer mWaitTimer;
|
||||
S32 mLastRequest;
|
||||
std::map<LLUUID, bool> mTextureChecked;
|
||||
bool mExported;
|
||||
bool mAborted;
|
||||
bool mExportError;
|
||||
|
||||
|
||||
typedef std::vector<LLUUID> id_list_t;
|
||||
typedef std::vector<std::string> string_list_t;
|
||||
id_list_t mTextures;
|
||||
string_list_t mTextureNames;
|
||||
|
||||
uuid_vec_t mInventoryRequests;
|
||||
uuid_vec_t mAssetRequests;
|
||||
};
|
||||
|
||||
|
||||
class FSExportCacheReadResponder : public LLTextureCache::ReadResponder
|
||||
{
|
||||
LOG_CLASS(FSExportCacheReadResponder);
|
||||
public:
|
||||
FSExportCacheReadResponder(const LLUUID& id, LLImageFormatted* image);
|
||||
|
||||
void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal);
|
||||
virtual void completed(bool success);
|
||||
|
||||
private:
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
LLUUID mID;
|
||||
};
|
||||
|
||||
class FSFloaterObjectExport : public LLFloater
|
||||
{
|
||||
public:
|
||||
FSFloaterObjectExport(const LLSD& key);
|
||||
virtual ~FSFloaterObjectExport();
|
||||
virtual BOOL postBuild();
|
||||
|
||||
void onCloseBtn();
|
||||
void updateProgress(const std::string message);
|
||||
|
||||
private:
|
||||
LLScrollListCtrl* mOutputList;
|
||||
class FSExportCacheReadResponder : public LLTextureCache::ReadResponder
|
||||
{
|
||||
LOG_CLASS(FSExportCacheReadResponder);
|
||||
public:
|
||||
FSExportCacheReadResponder(const LLUUID& id, LLImageFormatted* image, FSFloaterObjectExport* parent);
|
||||
|
||||
void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal);
|
||||
virtual void completed(bool success);
|
||||
|
||||
private:
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
LLUUID mID;
|
||||
FSFloaterObjectExport* mParent;
|
||||
};
|
||||
};
|
||||
|
||||
#endif // FS_FSEXPORT_H
|
||||
|
|
@ -64,23 +64,23 @@
|
|||
#include "llvfile.h"
|
||||
#include "llvfs.h"
|
||||
#include "llvolumemessage.h"
|
||||
#include "fsexportperms.h"
|
||||
#include "material_codes.h"
|
||||
#include <boost/algorithm/string_regex.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
FSFloaterImport::FSFloaterImport(const LLSD& key) :
|
||||
LLFloater(key),
|
||||
FSFloaterImport::FSFloaterImport(const LLSD& filename) :
|
||||
LLFloater(filename),
|
||||
mCreatingActive(false),
|
||||
mLinkset(0),
|
||||
mObject(0),
|
||||
mPrim(0),
|
||||
mImportState(IDLE),
|
||||
mFileReady(false)
|
||||
mFileFullName(filename),
|
||||
mObjectCreatedCallback()
|
||||
{
|
||||
mInstance = this;
|
||||
|
||||
mCommitCallbackRegistrar.add("Import.PickFile",boost::bind(&FSFloaterImport::onClickBtnPickFile,this));
|
||||
mCommitCallbackRegistrar.add("Import.ImportLinkset",boost::bind(&FSFloaterImport::onClickBtnImport,this));
|
||||
mCommitCallbackRegistrar.add("Import.UploadAsset",boost::bind(&FSFloaterImport::onClickCheckBoxUploadAsset,this));
|
||||
mCommitCallbackRegistrar.add("Import.TempAsset",boost::bind(&FSFloaterImport::onClickCheckBoxTempAsset,this));
|
||||
|
||||
|
|
@ -95,6 +95,10 @@ FSFloaterImport::~FSFloaterImport()
|
|||
{
|
||||
LL_WARNS("import") << "FSFloaterImport::~FSFloaterImport() failed to delete idle callback" << LL_ENDL;
|
||||
}
|
||||
if (mObjectCreatedCallback.connected())
|
||||
{
|
||||
mObjectCreatedCallback.disconnect();
|
||||
}
|
||||
|
||||
gSavedSettings.setBOOL("ShowNewInventory", mSavedSettingShowNewInventory);
|
||||
}
|
||||
|
|
@ -107,6 +111,9 @@ BOOL FSFloaterImport::postBuild()
|
|||
getChild<LLCheckBoxCtrl>("temp_asset")->setVisible(FALSE);
|
||||
getChild<LLCheckBoxCtrl>("temp_asset")->set(FALSE);
|
||||
}
|
||||
getChild<LLButton>("import_btn")->setCommitCallback(boost::bind(&FSFloaterImport::onClickBtnImport, this));
|
||||
loadFile();
|
||||
populateBackupInfo();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -189,39 +196,30 @@ void FSFloaterImport::onIdle()
|
|||
}
|
||||
}
|
||||
|
||||
void FSFloaterImport::onClickBtnPickFile()
|
||||
void FSFloaterImport::loadFile()
|
||||
{
|
||||
// pick a file
|
||||
LLFilePicker& file_picker = LLFilePicker::instance();
|
||||
if(!file_picker.getOpenFile(LLFilePicker::FFLOAD_IMPORT))
|
||||
{
|
||||
// User canceled or we failed to acquire file.
|
||||
return;
|
||||
}
|
||||
mFileFullName = file_picker.getFirstFile();
|
||||
mFilePath = gDirUtilp->getDirName(mFileName);
|
||||
mFileName= gDirUtilp->getBaseFileName(mFileFullName);
|
||||
getChild<LLLineEditor>("filename")->setValue(LLSD(mFileName));
|
||||
mFilePath = gDirUtilp->getDirName(mFilename);
|
||||
mFilename = gDirUtilp->getBaseFileName(mFileFullName);
|
||||
|
||||
mFile.clear();
|
||||
mManifest.clear();
|
||||
mTextureQueue.clear();
|
||||
mAnimQueue.clear();
|
||||
mSoundQueue.clear();
|
||||
mFileReady = false;
|
||||
mLinksetSize = 0;
|
||||
mTexturesTotal = 0;
|
||||
mAnimsTotal = 0;
|
||||
mSoundsTotal = 0;
|
||||
|
||||
bool file_loaded = false;
|
||||
llifstream filestream(mFileFullName, std::ios_base::in | std::ios_base::binary);
|
||||
if(filestream.is_open())
|
||||
{
|
||||
filestream.seekg(0, std::ios::end);
|
||||
S32 file_size = (S32)filestream.tellg();
|
||||
filestream.seekg(0, std::ios::beg);
|
||||
if (unzip_llsd(mFile, filestream, file_size))
|
||||
if (unzip_llsd(mManifest, filestream, file_size))
|
||||
{
|
||||
mFileReady = true;
|
||||
file_loaded = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -234,22 +232,22 @@ void FSFloaterImport::onClickBtnPickFile()
|
|||
}
|
||||
filestream.close();
|
||||
|
||||
if (mFileReady)
|
||||
if (file_loaded)
|
||||
{
|
||||
if (mFile.has("format_version") && mFile["format_version"].asInteger() == 1)
|
||||
if (mManifest.has("format_version") && mManifest["format_version"].asInteger() <= OXP_FORMAT_VERSION)
|
||||
{
|
||||
LLSD& linksetsd = mFile["linkset"];
|
||||
LLSD& linksetsd = mManifest["linkset"];
|
||||
U32 prims = 0;
|
||||
for (LLSD::array_iterator linkset_iter = linksetsd.beginArray();
|
||||
linkset_iter != linksetsd.endArray();
|
||||
++linkset_iter)
|
||||
{
|
||||
LLSD& objectsd = mFile["linkset"][mLinksetSize];
|
||||
LLSD& objectsd = mManifest["linkset"][mLinksetSize];
|
||||
for (LLSD::array_iterator prim_iter = objectsd.beginArray();
|
||||
prim_iter != objectsd.endArray();
|
||||
++prim_iter)
|
||||
{
|
||||
processPrim(mFile["prim"][(*prim_iter).asString()]);
|
||||
processPrim(mManifest["prim"][(*prim_iter).asString()]);
|
||||
prims++;
|
||||
}
|
||||
mLinksetSize++;
|
||||
|
|
@ -277,20 +275,34 @@ void FSFloaterImport::onClickBtnPickFile()
|
|||
LL_DEBUGS("import") << "Linkset size is " << mLinksetSize << LL_ENDL;
|
||||
if (mLinksetSize != 0)
|
||||
{
|
||||
getChild<LLButton>("import_file")->setEnabled(TRUE);
|
||||
getChild<LLButton>("import_btn")->setEnabled(TRUE);
|
||||
getChild<LLCheckBoxCtrl>("do_not_attach")->setEnabled(TRUE);
|
||||
getChild<LLCheckBoxCtrl>("region_position")->setEnabled(TRUE);
|
||||
getChild<LLCheckBoxCtrl>("upload_asset")->setEnabled(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
getChild<LLButton>("import_file")->setEnabled(FALSE);
|
||||
getChild<LLButton>("import_btn")->setEnabled(FALSE);
|
||||
getChild<LLCheckBoxCtrl>("do_not_attach")->setEnabled(FALSE);
|
||||
getChild<LLCheckBoxCtrl>("region_position")->setEnabled(FALSE);
|
||||
getChild<LLCheckBoxCtrl>("upload_asset")->setEnabled(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void FSFloaterImport::populateBackupInfo()
|
||||
{
|
||||
childSetTextArg("filename_text", "[FILENAME]", mFilename);
|
||||
childSetTextArg("client_text", "[VERSION]", mManifest["format_version"].asString());
|
||||
childSetTextArg("client_text", "[CLIENT]", (mManifest.has("client") ? mManifest["client"].asString() : LLTrans::getString("Unknown")));
|
||||
childSetTextArg("author_text", "[AUTHOR]", (mManifest.has("author") ? mManifest["author"].asString() : LLTrans::getString("Unknown")));
|
||||
childSetTextArg("author_text", "[GRID]", (mManifest.has("grid") ? "@ " + mManifest["grid"].asString() : LLTrans::getString("Unknown")));
|
||||
childSetTextArg("creation_date_text", "[DATE_STRING]", (mManifest.has("creation_date") ? mManifest["creation_date"].asString(): LLTrans::getString("Unknown")));
|
||||
|
||||
LLUIString title = getString("floater_title");
|
||||
title.setArg("[FILENAME]", mFilename);
|
||||
setTitle(title);
|
||||
}
|
||||
|
||||
void FSFloaterImport::processPrim(LLSD& prim)
|
||||
{
|
||||
if (prim.has("texture"))
|
||||
|
|
@ -319,21 +331,21 @@ void FSFloaterImport::processPrim(LLSD& prim)
|
|||
content_iter != contentsd.endArray();
|
||||
++content_iter)
|
||||
{
|
||||
if (!mFile["inventory"].has((*content_iter).asString()))
|
||||
if (!mManifest["inventory"].has((*content_iter).asString()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
LLAssetType::EType asset_type = LLAssetType::lookup(mFile["inventory"][(*content_iter).asString()]["type"].asString().c_str());
|
||||
LLUUID asset_id = mFile["inventory"][(*content_iter).asString()]["asset_id"].asUUID();
|
||||
LLAssetType::EType asset_type = LLAssetType::lookup(mManifest["inventory"][(*content_iter).asString()]["type"].asString().c_str());
|
||||
LLUUID asset_id = mManifest["inventory"][(*content_iter).asString()]["asset_id"].asUUID();
|
||||
|
||||
if (!mFile["asset"].has(asset_id.asString()))
|
||||
if (!mManifest["asset"].has(asset_id.asString()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
addAsset(asset_id, asset_type);
|
||||
std::vector<U8> buffer = mFile["asset"][asset_id.asString()]["data"].asBinary();
|
||||
std::vector<U8> buffer = mManifest["asset"][asset_id.asString()]["data"].asBinary();
|
||||
|
||||
switch(asset_type)
|
||||
{
|
||||
|
|
@ -405,7 +417,7 @@ void FSFloaterImport::processPrim(LLSD& prim)
|
|||
|
||||
void FSFloaterImport::addAsset(LLUUID asset_id, LLAssetType::EType asset_type)
|
||||
{
|
||||
if (!mFile["asset"].has(asset_id.asString()))
|
||||
if (!mManifest["asset"].has(asset_id.asString()))
|
||||
{
|
||||
LL_DEBUGS("import") << "Missing "<< asset_id.asString() << " asset data." << LL_ENDL;
|
||||
return;
|
||||
|
|
@ -469,8 +481,7 @@ void FSFloaterImport::onClickBtnImport()
|
|||
LL_DEBUGS("import") << "mStartPosition is " << mStartPosition << LL_ENDL;
|
||||
|
||||
// don't allow change during a long upload/import
|
||||
getChild<LLButton>("pick_file")->setEnabled(FALSE);
|
||||
getChild<LLButton>("import_file")->setEnabled(FALSE);
|
||||
getChild<LLButton>("import_btn")->setEnabled(FALSE);
|
||||
getChild<LLCheckBoxCtrl>("do_not_attach")->setEnabled(FALSE);
|
||||
getChild<LLCheckBoxCtrl>("region_position")->setEnabled(FALSE);
|
||||
getChild<LLCheckBoxCtrl>("upload_asset")->setEnabled(FALSE);
|
||||
|
|
@ -491,8 +502,7 @@ void FSFloaterImport::onClickBtnImport()
|
|||
LLBuyCurrencyHTML::openCurrencyFloater(LLTrans::getString("UploadingCosts", args), expected_upload_cost);
|
||||
|
||||
// re-enable the controls
|
||||
getChild<LLButton>("pick_file")->setEnabled(TRUE);
|
||||
getChild<LLButton>("import_file")->setEnabled(TRUE);
|
||||
getChild<LLButton>("import_btn")->setEnabled(TRUE);
|
||||
getChild<LLCheckBoxCtrl>("do_not_attach")->setEnabled(TRUE);
|
||||
getChild<LLCheckBoxCtrl>("region_position")->setEnabled(TRUE);
|
||||
getChild<LLCheckBoxCtrl>("upload_asset")->setEnabled(TRUE);
|
||||
|
|
@ -586,7 +596,7 @@ void FSFloaterImport::onClickCheckBoxTempAsset()
|
|||
void FSFloaterImport::importPrims()
|
||||
{
|
||||
mObjectSize = 0;
|
||||
LLSD& objectsd = mFile["linkset"][mLinkset];
|
||||
LLSD& objectsd = mManifest["linkset"][mLinkset];
|
||||
for (LLSD::array_iterator iter = objectsd.beginArray();
|
||||
iter != objectsd.endArray();
|
||||
++iter)
|
||||
|
|
@ -599,8 +609,8 @@ void FSFloaterImport::importPrims()
|
|||
LL_WARNS("import") << "Object size is to large to link. " << mObjectSize << " is greater then max linking size of " << MAX_PRIMS_PER_OBJECT << LL_ENDL;
|
||||
}
|
||||
mRootPosition = mStartPosition;
|
||||
LLUUID linkset_root_prim_uuid = mFile["linkset"][0][0].asUUID();
|
||||
LLSD& linkset_root_prim = mFile["prim"][linkset_root_prim_uuid.asString()];
|
||||
LLUUID linkset_root_prim_uuid = mManifest["linkset"][0][0].asUUID();
|
||||
LLSD& linkset_root_prim = mManifest["prim"][linkset_root_prim_uuid.asString()];
|
||||
mLinksetPosition.setValue(linkset_root_prim["position"]);
|
||||
mCreatingActive = true;
|
||||
createPrim();
|
||||
|
|
@ -615,9 +625,9 @@ void FSFloaterImport::createPrim()
|
|||
status.setArg("[PRIMS]", llformat("%u", mObjectSize));
|
||||
getChild<LLTextBox>("file_status_text")->setText(status.getString());
|
||||
|
||||
LLUUID prim_uuid = mFile["linkset"][mLinkset][mObject].asUUID();
|
||||
LLUUID prim_uuid = mManifest["linkset"][mLinkset][mObject].asUUID();
|
||||
LL_DEBUGS("import") << "Creating prim from " << prim_uuid.asString() << LL_ENDL;
|
||||
LLSD& prim = mFile["prim"][prim_uuid.asString()];
|
||||
LLSD& prim = mManifest["prim"][prim_uuid.asString()];
|
||||
|
||||
gMessageSystem->newMessageFast(_PREHASH_ObjectAdd);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
||||
|
|
@ -680,6 +690,13 @@ void FSFloaterImport::createPrim()
|
|||
{
|
||||
position = mRootPosition;
|
||||
}
|
||||
|
||||
if (mObjectCreatedCallback.connected())
|
||||
{
|
||||
mObjectCreatedCallback.disconnect();
|
||||
}
|
||||
mObjectCreatedCallback = gObjectList.setNewObjectCallback(boost::bind(&FSFloaterImport::processPrimCreated, this, _1));
|
||||
|
||||
LL_DEBUGS("import") << "Creating prim at position " << position << LL_ENDL;
|
||||
gMessageSystem->addVector3Fast(_PREHASH_RayStart, position);
|
||||
gMessageSystem->addVector3Fast(_PREHASH_RayEnd, position);
|
||||
|
|
@ -701,8 +718,8 @@ bool FSFloaterImport::processPrimCreated(LLViewerObject* object)
|
|||
|
||||
LLSelectMgr::getInstance()->selectObjectAndFamily(object, TRUE);
|
||||
|
||||
LLUUID prim_uuid = mFile["linkset"][mLinkset][mObject].asUUID();
|
||||
LLSD& prim = mFile["prim"][prim_uuid.asString()];
|
||||
LLUUID prim_uuid = mManifest["linkset"][mLinkset][mObject].asUUID();
|
||||
LLSD& prim = mManifest["prim"][prim_uuid.asString()];
|
||||
LL_DEBUGS("import") << "Processing prim " << prim_uuid.asString() << " for object " << object->getID().asString() << LL_ENDL;
|
||||
mPrimObjectMap[prim_uuid] = object->getID();
|
||||
U32 object_local_id = object->getLocalID();
|
||||
|
|
@ -949,13 +966,13 @@ bool FSFloaterImport::processPrimCreated(LLViewerObject* object)
|
|||
content_iter != contentsd.endArray();
|
||||
++content_iter)
|
||||
{
|
||||
if (!mFile["inventory"].has((*content_iter).asString()))
|
||||
if (!mManifest["inventory"].has((*content_iter).asString()))
|
||||
{
|
||||
LL_WARNS("import") << "Inventory content " << (*content_iter) << " was not found in import file." << LL_ENDL;
|
||||
continue;
|
||||
}
|
||||
|
||||
LLSD& item_sd = mFile["inventory"][(*content_iter).asString()];
|
||||
LLSD& item_sd = mManifest["inventory"][(*content_iter).asString()];
|
||||
LLUUID asset_id = item_sd["asset_id"].asUUID();
|
||||
|
||||
if (asset_id.isNull())
|
||||
|
|
@ -1046,8 +1063,8 @@ void FSFloaterImport::postLink()
|
|||
return;
|
||||
}
|
||||
|
||||
LLUUID root_prim_uuid = mFile["linkset"][mLinkset][0].asUUID();
|
||||
LLSD& root_prim = mFile["prim"][root_prim_uuid.asString()];
|
||||
LLUUID root_prim_uuid = mManifest["linkset"][mLinkset][0].asUUID();
|
||||
LLSD& root_prim = mManifest["prim"][root_prim_uuid.asString()];
|
||||
if (root_prim.has("attachment_point") && !getChild<LLCheckBoxCtrl>("do_not_attach")->get())
|
||||
{
|
||||
LL_DEBUGS("import") << "Attaching to " << root_prim["attachment_point"].asInteger() << LL_ENDL;
|
||||
|
|
@ -1081,9 +1098,6 @@ void FSFloaterImport::postLink()
|
|||
LL_DEBUGS("import") << "Finished with " << mLinkset << " linksets and " << mObject << " prims in last linkset" << LL_ENDL;
|
||||
mObjectSelection = NULL;
|
||||
getChild<LLTextBox>("file_status_text")->setText(getString("file_status_done"));
|
||||
|
||||
// re-enable the controls, but force to pick file due to need to re-create the upload queues.
|
||||
getChild<LLButton>("pick_file")->setEnabled(TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1091,7 +1105,7 @@ void FSFloaterImport::postLink()
|
|||
mLinkset++;
|
||||
|
||||
mObjectSize = 0;
|
||||
LLSD& objectsd = mFile["linkset"][mLinkset];
|
||||
LLSD& objectsd = mManifest["linkset"][mLinkset];
|
||||
for (
|
||||
LLSD::array_iterator iter = objectsd.beginArray();
|
||||
iter != objectsd.endArray();
|
||||
|
|
@ -1101,8 +1115,8 @@ void FSFloaterImport::postLink()
|
|||
}
|
||||
LL_DEBUGS("import") << "Next linkset Object size is " << mObjectSize << LL_ENDL;
|
||||
|
||||
LLUUID root_prim_uuid = mFile["linkset"][mLinkset][0].asUUID();
|
||||
LLSD& root_prim = mFile["prim"][root_prim_uuid.asString()];
|
||||
LLUUID root_prim_uuid = mManifest["linkset"][mLinkset][0].asUUID();
|
||||
LLSD& root_prim = mManifest["prim"][root_prim_uuid.asString()];
|
||||
LLVector3 root_prim_location(root_prim["position"]);
|
||||
mRootPosition = mStartPosition + (root_prim_location - mLinksetPosition);
|
||||
createPrim();
|
||||
|
|
@ -1143,11 +1157,11 @@ void FSFloaterImport::setPrimPosition(U8 type, LLViewerObject* object, LLVector3
|
|||
|
||||
void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item)
|
||||
{
|
||||
bool tempary = false;
|
||||
std::vector<U8> asset_data = mFile["asset"][asset_id.asString()]["data"].asBinary();
|
||||
std::string name = mFile["asset"][asset_id.asString()]["name"].asString();
|
||||
std::string description = mFile["asset"][asset_id.asString()]["description"].asString();
|
||||
LLAssetType::EType asset_type = LLAssetType::lookup(mFile["asset"][asset_id.asString()]["type"].asString().c_str());
|
||||
bool temporary = false;
|
||||
std::vector<U8> asset_data = mManifest["asset"][asset_id.asString()]["data"].asBinary();
|
||||
std::string name = mManifest["asset"][asset_id.asString()]["name"].asString();
|
||||
std::string description = mManifest["asset"][asset_id.asString()]["description"].asString();
|
||||
LLAssetType::EType asset_type = LLAssetType::lookup(mManifest["asset"][asset_id.asString()]["type"].asString().c_str());
|
||||
std::string url;
|
||||
LLSD body = LLSD::emptyMap();
|
||||
LLFolderType::EType folder_type = LLFolderType::assetTypeToFolderType(asset_type);
|
||||
|
|
@ -1165,8 +1179,8 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item)
|
|||
{
|
||||
case LLAssetType::AT_TEXTURE:
|
||||
{
|
||||
tempary = getChild<LLCheckBoxCtrl>("temp_asset")->get();
|
||||
if (tempary)
|
||||
temporary = getChild<LLCheckBoxCtrl>("temp_asset")->get();
|
||||
if (temporary)
|
||||
{
|
||||
url = gAgent.getRegion()->getCapability("UploadBakedTexture");
|
||||
}
|
||||
|
|
@ -1180,8 +1194,8 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item)
|
|||
break;
|
||||
case LLAssetType::AT_SOUND:
|
||||
{
|
||||
tempary = getChild<LLCheckBoxCtrl>("temp_asset")->get();
|
||||
if (tempary)
|
||||
temporary = getChild<LLCheckBoxCtrl>("temp_asset")->get();
|
||||
if (temporary)
|
||||
{
|
||||
// skip upload due to no temp support for sound
|
||||
nextAsset(LLUUID::null, asset_id, asset_type);
|
||||
|
|
@ -1296,8 +1310,8 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item)
|
|||
break;
|
||||
case LLAssetType::AT_ANIMATION:
|
||||
{
|
||||
tempary = getChild<LLCheckBoxCtrl>("temp_asset")->get();
|
||||
if (tempary)
|
||||
temporary = getChild<LLCheckBoxCtrl>("temp_asset")->get();
|
||||
if (temporary)
|
||||
{
|
||||
// no temp support, skip
|
||||
nextAsset(LLUUID::null, asset_id, asset_type);
|
||||
|
|
@ -1421,7 +1435,7 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item)
|
|||
FSResourceData* fs_data = new FSResourceData;
|
||||
fs_data->uuid = asset_id;
|
||||
fs_data->user_data = this;
|
||||
fs_data->tempary = tempary;
|
||||
fs_data->temporary = temporary;
|
||||
fs_data->inventory_item = inventory_item;
|
||||
fs_data->wearable_type = wearable_type;
|
||||
fs_data->asset_type = asset_type;
|
||||
|
|
@ -1453,9 +1467,9 @@ void FSFloaterImport::uploadAsset(LLUUID asset_id, LLUUID inventory_item)
|
|||
asset_type,
|
||||
FSFloaterImport::onAssetUploadComplete,
|
||||
data,
|
||||
tempary,
|
||||
tempary,
|
||||
tempary);
|
||||
temporary,
|
||||
temporary,
|
||||
temporary);
|
||||
LL_DEBUGS("import") << "Asset upload via AssetStorage of " << new_asset_id.asString() << " of " << asset_id.asString() << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
|
@ -1485,7 +1499,7 @@ void FSFloaterImport::onAssetUploadComplete(const LLUUID& uuid, void* userdata,
|
|||
|
||||
if (fs_data->inventory_item.isNull())
|
||||
{
|
||||
if (fs_data->tempary)
|
||||
if (fs_data->temporary)
|
||||
{
|
||||
LLUUID item_id;
|
||||
item_id.generate();
|
||||
|
|
@ -1803,7 +1817,7 @@ void FSAssetResponder::uploadComplete(const LLSD& content)
|
|||
|
||||
if (item_id.isNull())
|
||||
{
|
||||
if (fs_data->tempary)
|
||||
if (fs_data->temporary)
|
||||
{
|
||||
if (result == "complete")
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@
|
|||
#include "llfloater.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llresourcedata.h"
|
||||
#include "llsingleton.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "llviewerinventory.h"
|
||||
#include "llviewerobject.h"
|
||||
|
|
@ -40,7 +39,7 @@ struct FSResourceData
|
|||
{
|
||||
LLUUID uuid;
|
||||
void* user_data;
|
||||
bool tempary;
|
||||
bool temporary;
|
||||
LLAssetType::EType asset_type;
|
||||
LLUUID inventory_item;
|
||||
LLWearableType::EType wearable_type;
|
||||
|
|
@ -50,18 +49,17 @@ struct FSResourceData
|
|||
|
||||
#include "llassetuploadresponders.h"
|
||||
|
||||
class FSFloaterImport : public LLFloater, public LLSingleton<FSFloaterImport>
|
||||
class FSFloaterImport : public LLFloater
|
||||
{
|
||||
LOG_CLASS(FSFloaterImport);
|
||||
public:
|
||||
FSFloaterImport(const LLSD &);
|
||||
FSFloaterImport(const LLSD &filename);
|
||||
virtual ~FSFloaterImport();
|
||||
virtual BOOL postBuild();
|
||||
|
||||
static void onIdle(void *user_data);
|
||||
|
||||
void onClickBtnPickFile();
|
||||
void onClickBtnImport();
|
||||
|
||||
void onClickCheckBoxUploadAsset();
|
||||
void onClickCheckBoxTempAsset();
|
||||
bool processPrimCreated(LLViewerObject* object);
|
||||
|
|
@ -80,6 +78,9 @@ private:
|
|||
} FSImportState;
|
||||
FSImportState mImportState;
|
||||
|
||||
void loadFile();
|
||||
void populateBackupInfo();
|
||||
void onClickBtnImport();
|
||||
void createPrim();
|
||||
void postLink();
|
||||
void onIdle();
|
||||
|
|
@ -89,9 +90,9 @@ private:
|
|||
void searchInventory(LLUUID asset_id, LLViewerObject* object, std::string prim_name);
|
||||
void processPrim(LLSD& prim);
|
||||
|
||||
LLSD mFile;
|
||||
LLSD mManifest;
|
||||
std::string mFileFullName;
|
||||
std::string mFileName;
|
||||
std::string mFilename;
|
||||
std::string mFilePath;
|
||||
bool mCreatingActive;
|
||||
FSFloaterImport* mInstance;
|
||||
|
|
@ -106,7 +107,6 @@ private:
|
|||
S32 mLinksetSize;
|
||||
S32 mObjectSize;
|
||||
LLObjectSelectionHandle mObjectSelection;
|
||||
bool mFileReady;
|
||||
uuid_vec_t mTextureQueue;
|
||||
U32 mTexturesTotal;
|
||||
uuid_vec_t mSoundQueue;
|
||||
|
|
@ -117,6 +117,7 @@ private:
|
|||
U32 mAssetsTotal;
|
||||
std::map<LLUUID,LLUUID> mAssetMap;
|
||||
BOOL mSavedSettingShowNewInventory;
|
||||
boost::signals2::connection mObjectCreatedCallback;
|
||||
|
||||
struct FSInventoryQueue
|
||||
{
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@
|
|||
#include "floatermedialists.h"
|
||||
#include "fsareasearch.h"
|
||||
#include "fscontactsfloater.h"
|
||||
#include "fsexport.h"
|
||||
#include "fsfloaterexport.h"
|
||||
#include "fsfloaterblocklist.h"
|
||||
#include "fsfloatergroup.h"
|
||||
#include "fsfloatergrouptitles.h"
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@
|
|||
// [/RLVa:KB]
|
||||
#include "fslslbridge.h"
|
||||
#include "fscommon.h"
|
||||
#include "fsexport.h"
|
||||
#include "fsfloaterexport.h"
|
||||
#include "fscontactsfloater.h" // <FS:Zi> Display group list in contacts floater
|
||||
#include "fspose.h" // <FS:CR> FIRE-4345: Undeform
|
||||
#include "fswsassetblacklist.h"
|
||||
|
|
@ -10060,7 +10060,11 @@ class FSObjectExport : public view_listener_t
|
|||
{
|
||||
bool handleEvent( const LLSD& userdata)
|
||||
{
|
||||
FSExport::getInstance()->exportSelection();
|
||||
LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
||||
if (objectp)
|
||||
{
|
||||
LLFloaterReg::showInstance("fs_export", LLSD(objectp->getID()), TAKE_FOCUS_YES);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -640,6 +640,17 @@ class LLFileUploadBulk : public view_listener_t
|
|||
}
|
||||
};
|
||||
|
||||
// <FS:CR> Import Linkset
|
||||
class FSFileImportLinkset : public view_listener_t
|
||||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
(new LLGenericLoadFilePicker(LLFilePicker::FFLOAD_IMPORT, boost::bind(&show_floater_callback, "fs_import", _1, LLFilePicker::FFLOAD_IMPORT)))->getFile();
|
||||
return TRUE;
|
||||
}
|
||||
};
|
||||
// </FS:CR>
|
||||
|
||||
void upload_error(const std::string& error_message, const std::string& label, const std::string& filename, const LLSD& args)
|
||||
{
|
||||
llwarns << error_message << llendl;
|
||||
|
|
@ -1588,6 +1599,7 @@ void init_menu_file()
|
|||
view_listener_t::addEnable(new LLFileEnableUploadModel(), "File.EnableUploadModel");
|
||||
view_listener_t::addMenu(new LLMeshEnabled(), "File.MeshEnabled");
|
||||
view_listener_t::addMenu(new LLMeshUploadVisible(), "File.VisibleUploadModel");
|
||||
view_listener_t::addCommit(new FSFileImportLinkset(), "File.ImportLinkset"); // <FS:CR> Import linkset item
|
||||
|
||||
// "File.SaveTexture" moved to llpanelmaininventory so that it can be properly handled.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -226,6 +226,13 @@ void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,
|
|||
S32 gFullObjectUpdates = 0;
|
||||
S32 gTerseObjectUpdates = 0;
|
||||
|
||||
// <FS:CR> Object Import
|
||||
boost::signals2::connection LLViewerObjectList::setNewObjectCallback(new_object_callback_t cb)
|
||||
{
|
||||
return mNewObjectSignal.connect(cb);
|
||||
}
|
||||
// </FS:CR>
|
||||
|
||||
void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
|
||||
void** user_data,
|
||||
U32 i,
|
||||
|
|
@ -267,10 +274,10 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
|
|||
// <FS:Techwolf Lupindo> import support
|
||||
bool import_handled = false;
|
||||
bool own_full_perm = (objectp->permYouOwner() && objectp->permModify() && objectp->permTransfer() && objectp->permCopy());
|
||||
FSFloaterImport* floater_import = LLFloaterReg::getTypedInstance<FSFloaterImport>("fs_import");
|
||||
if (floater_import && own_full_perm)
|
||||
if (own_full_perm)
|
||||
{
|
||||
import_handled = floater_import->processPrimCreated(objectp);
|
||||
import_handled = mNewObjectSignal(objectp);
|
||||
mNewObjectSignal.disconnect_all_slots();
|
||||
}
|
||||
if (!import_handled)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -135,6 +135,13 @@ public:
|
|||
void removeFromMap(LLViewerObject *objectp);
|
||||
|
||||
void clearDebugText();
|
||||
|
||||
// <FS:CR> Import
|
||||
typedef boost::function<bool (LLViewerObject* object)> new_object_callback_t;
|
||||
typedef boost::signals2::signal<bool (LLViewerObject* object)> new_object_signal_t;
|
||||
boost::signals2::connection setNewObjectCallback(new_object_callback_t cb);
|
||||
new_object_signal_t mNewObjectSignal;
|
||||
// </FS:CR>
|
||||
|
||||
////////////////////////////////////////////
|
||||
//
|
||||
|
|
|
|||
|
|
@ -5771,63 +5771,6 @@ Setzen Sie den Editorpfad in Anführungszeichen
|
|||
Umschalten des Präprozessors wird erst vollständig wirksam, nachdem der Editor geschlossen und neu geöffnet wurde.
|
||||
</string>
|
||||
|
||||
<string name="export_started">
|
||||
Beginne Export...
|
||||
</string>
|
||||
<string name="export_finished">
|
||||
Export beendet.
|
||||
</string>
|
||||
<string name="export_fail_no_mesh">
|
||||
Der Export von Mesh wird derzeit nicht unterstützt. Export abgebrochen.
|
||||
</string>
|
||||
<string name="export_nothing_exported">
|
||||
Kein Export durchgeführt. Backup wurde nicht erstellt.
|
||||
</string>
|
||||
<string name="export_node_not_found">
|
||||
LLSelect-Knoten für [OBJECT] gefunden. Verwende Standard-Prim.
|
||||
</string>
|
||||
<string name="export_failed_export_check">
|
||||
Berechtigungen für [OBJECT] unzureichend. Verwende Standard-Prim.
|
||||
</string>
|
||||
<string name="export_asset_failed_export_check">
|
||||
Berechtigungen für [ITEM] unzureichend - übersprungen...
|
||||
</string>
|
||||
<string name="export_failed_export_null_texture">
|
||||
Versuchter Export einer leeren Textur.
|
||||
</string>
|
||||
<string name="export_loading_texture">
|
||||
Lade Textur [ITEM]...
|
||||
</string>
|
||||
<string name="export_saving_texture">
|
||||
Textur [TEXTURE] erfolgreich gespeichert.
|
||||
</string>
|
||||
<string name="export_saving_asset">
|
||||
Speichere [ITEM]...
|
||||
</string>
|
||||
<string name="export_failed_to_receive_texture">
|
||||
Fehler beim Laden von Textur [TEXTURE].
|
||||
</string>
|
||||
<string name="export_received_null_texture">
|
||||
Leere Textur [TEXTURE] empfangen.
|
||||
</string>
|
||||
<string name="export_item_not_exportable">
|
||||
[ITEM] wird aktuell nicht vom Exporter unterstützt - übersprungen...
|
||||
</string>
|
||||
<string name="export_failed_fetch">
|
||||
[ITEM] konnte nicht geladen werden. (Status [STATUS] [EXT_STATUS])
|
||||
</string>
|
||||
<string name="export_requesting_asset">
|
||||
Fordere Asset [ITEM] an...
|
||||
</string>
|
||||
<string name="export_rerequesting_inventory">
|
||||
Fordere Inventar von [ITEM] erneut an.
|
||||
</string>
|
||||
<string name="export_rerequesting_texture">
|
||||
Fordere Textur [ITEM] erneut an.
|
||||
</string>
|
||||
<string name="export_failed_to_load">
|
||||
Asset [ITEM] konnte nicht geladen werden.
|
||||
</string>
|
||||
<string name="skin_defaults_starlight_location">
|
||||
Die Anzeige der aktuellen Position in der Menüleiste wurde als Standard für Starlight-Oberflächendesigns deaktiviert.
|
||||
</string>
|
||||
|
|
|
|||
|
|
@ -1,32 +1,161 @@
|
|||
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
|
||||
<floater
|
||||
name="export_log"
|
||||
title="Export Object"
|
||||
width="250"
|
||||
height="300"
|
||||
min_width="104"
|
||||
min_height="100"
|
||||
height="162"
|
||||
width="500"
|
||||
help_topic="fs_export"
|
||||
layout="topleft"
|
||||
legacy_header_height="18"
|
||||
name="floater_fs_export"
|
||||
min_width="252"
|
||||
min_height="168"
|
||||
save_rect="true"
|
||||
can_resize="true"
|
||||
can_minimize="true"
|
||||
can_close="true"
|
||||
can_drag_on_left="false">
|
||||
<scroll_list
|
||||
enabled="true"
|
||||
title="Backup objects...">
|
||||
<floater.string name="title_floater">
|
||||
Backup [OBJECT] to Hard Disk...
|
||||
</floater.string>
|
||||
<floater.string name="title_working">
|
||||
Backup [OBJECT] working - Gathering information...
|
||||
</floater.string>
|
||||
<floater.string name="title_inventory">
|
||||
Backup [OBJECT] working - Fetching inventory...
|
||||
</floater.string>
|
||||
<floater.string name="title_assets">
|
||||
Backup [OBJECT] working - Fetching assets...
|
||||
</floater.string>
|
||||
<floater.string name="title_textures">
|
||||
Backup [OBJECT] working - Fetching textures...
|
||||
</floater.string>
|
||||
<layout_stack
|
||||
follows="all"
|
||||
height="270"
|
||||
layout="topleft"
|
||||
left="4"
|
||||
name="export_output"
|
||||
top="4"
|
||||
width="242" />
|
||||
<button
|
||||
layout="topleft"
|
||||
follows="right|bottom"
|
||||
height="23"
|
||||
label="OK"
|
||||
name="close_btn"
|
||||
top_pad="1"
|
||||
left="153"
|
||||
width="90" />
|
||||
width="500"
|
||||
height="142"
|
||||
left="0"
|
||||
orientation="horizontal"
|
||||
top="18"
|
||||
show_drag_handle="true"
|
||||
name="resizing_stack">
|
||||
<layout_panel
|
||||
follows="left|top|bottom"
|
||||
layout="topleft"
|
||||
top="18"
|
||||
left="0"
|
||||
width="250"
|
||||
height="142"
|
||||
name="control_panel">
|
||||
<text
|
||||
follows="left|top"
|
||||
height="15"
|
||||
layout="topleft"
|
||||
left="4"
|
||||
name="SelectionInfoText"
|
||||
top="2"
|
||||
width="235">
|
||||
Selection Info
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
height="15"
|
||||
layout="topleft"
|
||||
name="exportable_prims"
|
||||
left_delta="8"
|
||||
top_pad="2"
|
||||
width="235">
|
||||
Exportable prims: [COUNT]/[TOTAL]
|
||||
</text>
|
||||
<text
|
||||
follows="left|top"
|
||||
height="15"
|
||||
layout="topleft"
|
||||
name="exportable_textures"
|
||||
top_pad="2"
|
||||
width="235">
|
||||
Exportable textures: [COUNT]/[TOTAL]
|
||||
</text>
|
||||
<text
|
||||
follows="left|bottom"
|
||||
height="15"
|
||||
layout="topleft"
|
||||
left="4"
|
||||
name="OptionsText"
|
||||
top="82"
|
||||
width="235">
|
||||
Options:
|
||||
</text>
|
||||
<check_box
|
||||
control_name="FSExportContents"
|
||||
follows="left|bottom"
|
||||
height="16"
|
||||
label="Backup object contents to disk"
|
||||
layout="topleft"
|
||||
name="contents_check"
|
||||
top_pad="2"
|
||||
width="235" />
|
||||
<button
|
||||
layout="topleft"
|
||||
follows="left|bottom"
|
||||
height="23"
|
||||
label="Save as..."
|
||||
name="export_btn"
|
||||
top="117"
|
||||
left="4"
|
||||
width="122" />
|
||||
</layout_panel>
|
||||
<layout_panel
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
top="18"
|
||||
left="250"
|
||||
width="250"
|
||||
height="142"
|
||||
name="contents_panel">
|
||||
<tab_container
|
||||
layout="topleft"
|
||||
follows="all"
|
||||
top="1"
|
||||
left="0"
|
||||
right="-1"
|
||||
bottom="142"
|
||||
name="ls_tabs"
|
||||
tab_width="119"
|
||||
tab_position="top">
|
||||
<panel
|
||||
label="Objects"
|
||||
name="prims_panel">
|
||||
<scroll_list
|
||||
enabled="true"
|
||||
background_visible="true"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
name="selected_objects"
|
||||
left="4"
|
||||
right="-1"
|
||||
top="0"
|
||||
bottom="-1"
|
||||
height="94">
|
||||
<columns
|
||||
name="icon"
|
||||
width="20" />
|
||||
<columns
|
||||
name="name"
|
||||
relwidth="1" />
|
||||
</scroll_list>
|
||||
</panel>
|
||||
<panel
|
||||
label="Textures"
|
||||
name="texture_panel">
|
||||
<scroll_container
|
||||
opaque="false"
|
||||
follows="all"
|
||||
layout="topleft"
|
||||
name="selected_textures"
|
||||
top="2"
|
||||
left="0"
|
||||
right="-1"
|
||||
bottom="-1" />
|
||||
</panel>
|
||||
</tab_container>
|
||||
</layout_panel>
|
||||
</layout_stack>
|
||||
</floater>
|
||||
|
|
@ -4,11 +4,15 @@
|
|||
help_topic="fs_import"
|
||||
title="Object Import"
|
||||
width="210"
|
||||
height="145"
|
||||
height="206"
|
||||
save_rect="true"
|
||||
can_resize="false"
|
||||
can_minimize="true"
|
||||
can_close="true">
|
||||
<floater.string
|
||||
name="floater_title">
|
||||
Import [FILENAME]
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="file_status">
|
||||
[LINKSETS] linksets. [PRIMS] prims. [TEXTURES] textures.
|
||||
|
|
@ -50,54 +54,75 @@
|
|||
name="upload_cost">
|
||||
Total cost of uploads: $L [COST].
|
||||
</floater.string>
|
||||
<line_editor
|
||||
name="filename"
|
||||
bevel_style="in"
|
||||
border_style="line"
|
||||
border_thickness="1"
|
||||
enabled="false"
|
||||
height="20"
|
||||
width="200"
|
||||
left="5"
|
||||
follows="left|top"
|
||||
max_length_chars="256" />
|
||||
<floater.string
|
||||
name="object">
|
||||
object
|
||||
</floater.string>
|
||||
<floater.string
|
||||
name="objects">
|
||||
objects
|
||||
</floater.string>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="14"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
name="filename_text"
|
||||
width="200">
|
||||
[FILENAME]
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="14"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
name="creation_date_text"
|
||||
width="200">
|
||||
Created on [DATE_STRING]
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="14"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
name="author_text"
|
||||
use_ellipses="true"
|
||||
width="200">
|
||||
by [AUTHOR] [GRID]
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="14"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
name="client_text"
|
||||
use_ellipses="true"
|
||||
width="200">
|
||||
Client: [CLIENT] v.[VERSION]
|
||||
</text>
|
||||
<text
|
||||
type="string"
|
||||
length="1"
|
||||
follows="left|top"
|
||||
height="26"
|
||||
height="52"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
name="file_status_text"
|
||||
width="200">
|
||||
Select a file.
|
||||
</text>
|
||||
<button
|
||||
name="pick_file"
|
||||
label="Choose File"
|
||||
height="20"
|
||||
width="97"
|
||||
left="5"
|
||||
follows="left|top">
|
||||
<button.commit_callback
|
||||
function="Import.PickFile" />
|
||||
</button>
|
||||
<button
|
||||
name="import_file"
|
||||
label="Import"
|
||||
height="20"
|
||||
width="97"
|
||||
left_delta="103"
|
||||
enabled="false"
|
||||
follows="left|top" >
|
||||
<button.commit_callback
|
||||
function="Import.ImportLinkset" />
|
||||
</button>
|
||||
<check_box
|
||||
follows="top|left"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
enabled="false"
|
||||
name="do_not_attach"
|
||||
label="Do not attach object"
|
||||
|
|
@ -106,21 +131,19 @@
|
|||
follows="top|left"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
enabled="false"
|
||||
name="region_position"
|
||||
label="Restore Region Position"
|
||||
top_pad="5"/>
|
||||
top_pad="1"/>
|
||||
<check_box
|
||||
follows="top|left"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left="5"
|
||||
width="90"
|
||||
enabled="false"
|
||||
name="upload_asset"
|
||||
label="Upload"
|
||||
top_pad="5" >
|
||||
top_pad="1" >
|
||||
<check_box.commit_callback
|
||||
function="Import.UploadAsset" />
|
||||
</check_box>
|
||||
|
|
@ -128,11 +151,29 @@
|
|||
follows="top|left"
|
||||
height="16"
|
||||
layout="topleft"
|
||||
left_delta="130"
|
||||
top_pad="1"
|
||||
left_delta="15"
|
||||
enabled="false"
|
||||
name="temp_asset"
|
||||
label="Temp" >
|
||||
<check_box.commit_callback
|
||||
function="Import.TempAsset" />
|
||||
</check_box>
|
||||
<button
|
||||
name="import_btn"
|
||||
label="Import"
|
||||
height="20"
|
||||
width="97"
|
||||
left="109"
|
||||
top_delta="-2"
|
||||
follows="right_bottom" />
|
||||
<loading_indicator
|
||||
visible="false"
|
||||
follows="left|top"
|
||||
height="18"
|
||||
layout="topleft"
|
||||
left="187"
|
||||
name="progress_indicator"
|
||||
top="110"
|
||||
width="18" />
|
||||
</floater>
|
||||
|
|
@ -363,8 +363,8 @@
|
|||
visibility_control="FSEnableObjectExports"
|
||||
name="import linkset">
|
||||
<menu_item_call.on_click
|
||||
function="Floater.Toggle"
|
||||
parameter="fs_import" />
|
||||
function="File.ImportLinkset"
|
||||
parameter="" />
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
|
||||
|
|
@ -1743,8 +1743,8 @@
|
|||
visibility_control="FSEnableObjectExports"
|
||||
name="import linkset">
|
||||
<menu_item_call.on_click
|
||||
function="Floater.Toggle"
|
||||
parameter="fs_import" />
|
||||
function="File.ImportLinkset"
|
||||
parameter="" />
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
<menu_item_separator/>
|
||||
|
|
|
|||
|
|
@ -11431,10 +11431,10 @@ Export finished and saved to [FILENAME].
|
|||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="ExportColladaFailed"
|
||||
name="ExportFailed"
|
||||
type="notify">
|
||||
<tag>Export</tag>
|
||||
Export failed.
|
||||
Export failed unexpectedly. Please see the log for details.
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
|
|
@ -11444,6 +11444,14 @@ Export failed.
|
|||
<tag>Export</tag>
|
||||
Successfully saved [OBJECT] to [FILENAME].
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="alertmodal.tga"
|
||||
name="ImportSuccess"
|
||||
type="notify">
|
||||
<tag>Export</tag>
|
||||
Successfully imported [COUNT] [OBJECT].
|
||||
</notification>
|
||||
|
||||
<notification
|
||||
icon="notifytip.tga"
|
||||
|
|
|
|||
|
|
@ -2588,27 +2588,6 @@ Try enclosing path to the editor with double quotes.
|
|||
<string name="TotalScriptCountChangeIncrease">Total scripts in region jumped from [OLD_VALUE] to [NEW_VALUE] ([DIFFERENCE]).</string>
|
||||
<string name="TotalScriptCountChangeDecrease">Total scripts in region dropped from [OLD_VALUE] to [NEW_VALUE] ([DIFFERENCE]).</string>
|
||||
<string name="preproc_toggle_warning">Toggling the preprocessor will not take full effect until you close and reopen this editor.</string>
|
||||
|
||||
<!-- <FS:CR> Exporter messages -->
|
||||
<string name="export_started">Beginning export...</string>
|
||||
<string name="export_finished">Export finished.</string>
|
||||
<string name="export_fail_no_mesh">Exporting mesh is not currently supported. Aborting export.</string>
|
||||
<string name="export_nothing_exported">Nothing was exported. Backup not created.</string>
|
||||
<string name="export_node_not_found">LLSelect node for [OBJECT] not found. Using default prim instead.</string>
|
||||
<string name="export_failed_export_check">[OBJECT] failed permissions check. Using default prim.</string>
|
||||
<string name="export_asset_failed_export_check">[ITEM] failed permissions check. Skipping.</string>
|
||||
<string name="export_failed_export_null_texture">Attempted to export null texture.</string>
|
||||
<string name="export_loading_texture">Loading texture [ITEM]...</string>
|
||||
<string name="export_saving_texture">Successfully saved texture [TEXTURE].</string>
|
||||
<string name="export_saving_asset">Saving [ITEM]...</string>
|
||||
<string name="export_failed_to_receive_texture">Failed to get texture [TEXTURE].</string>
|
||||
<string name="export_received_null_texture">Received null texture [TEXTURE].</string>
|
||||
<string name="export_item_not_exportable">[ITEM] is not currently supported by the exporter. Skipping.</string>
|
||||
<string name="export_failed_fetch">Could not retrieve [ITEM]. (Status [STATUS] [EXT_STATUS])</string>
|
||||
<string name="export_requesting_asset">Requesting asset [ITEM]...</string>
|
||||
<string name="export_rerequesting_inventory">Rerequesting inventory for [ITEM].</string>
|
||||
<string name="export_rerequesting_texture">Rerequesting texture [ITEM].</string>
|
||||
<string name="export_failed_to_load">Failed to load asset [ITEM].</string>
|
||||
|
||||
<!-- <FS:Zi> Notify user about preferences settings changes to skin defaults -->
|
||||
<string name="skin_defaults_starlight_location">Showing your current location in the menu bar was disabled as a default for the Starlight skin series.</string>
|
||||
|
|
|
|||
|
|
@ -5278,63 +5278,6 @@ Spróbuj załączyć ścieżkę do edytora w cytowaniu.
|
|||
<string name="preproc_toggle_warning">
|
||||
Przełączenie trybu preprocesora odniesie pełny skutek dopiero po zamknięciu i ponownym otwarciu tego edytora.
|
||||
</string>
|
||||
<string name="export_started">
|
||||
Rozpoczynanie eksportu...
|
||||
</string>
|
||||
<string name="export_finished">
|
||||
Eksportowanie zakończone.
|
||||
</string>
|
||||
<string name="export_fail_no_mesh">
|
||||
Eksportowanie meszy jest obecnie nieobsługiwane. Anulowano.
|
||||
</string>
|
||||
<string name="export_nothing_exported">
|
||||
Nic nie zostało wyeksportowane. Kopia nie została stworzona.
|
||||
</string>
|
||||
<string name="export_node_not_found">
|
||||
Nie znaleziono węzła obiektu [OBJECT] metodą LLSelect. Używam primy domyślnej zamiast tego.
|
||||
</string>
|
||||
<string name="export_failed_export_check">
|
||||
[OBJECT] nie ma odpowiednich zezwoleń. Używam primy domyślnej.
|
||||
</string>
|
||||
<string name="export_asset_failed_export_check">
|
||||
[ITEM] nie ma odpowiednich zezwoleń. Pomijam.
|
||||
</string>
|
||||
<string name="export_failed_export_null_texture">
|
||||
Próbowano eksportować pustą teksturę.
|
||||
</string>
|
||||
<string name="export_loading_texture">
|
||||
Ładowanie tekstury [ITEM]...
|
||||
</string>
|
||||
<string name="export_saving_texture">
|
||||
Pomyślnie zapisano teksturę [TEXTURE].
|
||||
</string>
|
||||
<string name="export_saving_asset">
|
||||
Zapisywanie [ITEM]...
|
||||
</string>
|
||||
<string name="export_failed_to_receive_texture">
|
||||
Nie powiodło się pobranie tekstury [TEXTURE].
|
||||
</string>
|
||||
<string name="export_received_null_texture">
|
||||
Otrzymano pustą teksturę: [TEXTURE].
|
||||
</string>
|
||||
<string name="export_item_not_exportable">
|
||||
[ITEM] jest obecnie nieobsługiwany przez eksporter. Pomijam.
|
||||
</string>
|
||||
<string name="export_failed_fetch">
|
||||
Nie można pobrać [ITEM]. (Status [STATUS] [EXT_STATUS])
|
||||
</string>
|
||||
<string name="export_requesting_asset">
|
||||
Pobieranie danych [ITEM]...
|
||||
</string>
|
||||
<string name="export_rerequesting_inventory">
|
||||
Pobieranie zawartości dla [ITEM].
|
||||
</string>
|
||||
<string name="export_rerequesting_texture">
|
||||
Pobieranie tekstury [ITEM].
|
||||
</string>
|
||||
<string name="export_failed_to_load">
|
||||
Nie powiodło się pobranie danych [ITEM].
|
||||
</string>
|
||||
<string name="skin_defaults_starlight_location">
|
||||
Pokazywanie Twojej obecnej lokalizacji w pasku menu zostało wyłączone, to domyślne zachowanie dla skórek linii StarLight.
|
||||
</string>
|
||||
|
|
|
|||
Loading…
Reference in New Issue