diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 46457dc8d1..1590856753 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -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
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 361f1111ae..38cb0ff8f8 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -20877,7 +20877,7 @@ Change of this parameter will affect the layout of buttons in notification toast
FSBuildPrefs_Temporary
+ FSExportContents
+
diff --git a/indra/newview/daeexport.cpp b/indra/newview/daeexport.cpp
index fa919a7072..dbcb35a77a 100644
--- a/indra/newview/daeexport.cpp
+++ b/indra/newview/daeexport.cpp
@@ -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(), ' ', '_');
diff --git a/indra/newview/daeexport.h b/indra/newview/daeexport.h
index d59c493b54..1d6dac19f7 100644
--- a/indra/newview/daeexport.h
+++ b/indra/newview/daeexport.h
@@ -127,7 +127,6 @@ private:
virtual ~ColladaExportFloater();
void onClickExport();
void onTextureExportCheck();
- void filepickerCallback();
void onCommitTextureType();
void saveTextures();
void addSelectedObjects();
diff --git a/indra/newview/fsexportperms.cpp b/indra/newview/fsexportperms.cpp
new file mode 100644
index 0000000000..f23e9673ae
--- /dev/null
+++ b/indra/newview/fsexportperms.cpp
@@ -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
+ *
+ * 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;
+}
+
diff --git a/indra/newview/fsexportperms.h b/indra/newview/fsexportperms.h
new file mode 100644
index 0000000000..5cf2d6e35c
--- /dev/null
+++ b/indra/newview/fsexportperms.h
@@ -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
+ *
+ * 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
diff --git a/indra/newview/fsexport.cpp b/indra/newview/fsfloaterexport.cpp
similarity index 64%
rename from indra/newview/fsexport.cpp
rename to indra/newview/fsfloaterexport.cpp
index 1433abc184..a09d44e5d6 100644
--- a/indra/newview/fsexport.cpp
+++ b/indra/newview/fsfloaterexport.cpp
@@ -1,10 +1,11 @@
/**
- * @file fsexport.cpp
+ * @file fsfloaterexport.cpp
* @brief export selected objects to an file using LLSD.
*
* $LicenseInfo:firstyear=2013&license=viewerlgpl$
* Phoenix Firestorm Viewer Source Code
* Copyright (c) 2013 Techwolf Lupindo
+ * Copyright (c) 2013 Cinder Roxley
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -27,12 +28,11 @@
#include "llviewerprecompiledheaders.h"
-#include "fsexport.h"
+#include "fsfloaterexport.h"
#include "llagent.h"
#include "llagentconstants.h"
#include "llagentdata.h"
-#include "llappviewer.h"
#include "llavatarnamecache.h"
#include "llbufferstream.h"
#include "llcallbacklist.h"
@@ -41,24 +41,26 @@
#include "llfilepicker.h"
#include "llimagej2c.h"
#include "llinventoryfunctions.h"
-#include "llmeshrepository.h"
#include "llmultigesture.h"
#include "llnotecard.h"
#include "llnotificationsutil.h"
+#include "llscrollcontainer.h"
#include "llsdserialize.h"
#include "llsdutil_math.h"
#include "llsdutil.h"
+#include "lltexturectrl.h"
#include "lltrans.h"
#include "llversioninfo.h"
#include "llvfile.h"
+#include "llviewercontrol.h"
#include "llviewerinventory.h"
+#include "llviewerpartsource.h"
#include "llviewernetwork.h"
#include "llviewerregion.h"
#include "llviewertexturelist.h"
#include "llvovolume.h"
-#include "llviewerpartsource.h"
-#include "llworld.h"
-#include "fscommon.h"
+#include "fsexportperms.h"
+
#include "llfloaterreg.h"
#include
@@ -66,16 +68,14 @@ const F32 MAX_TEXTURE_WAIT_TIME = 30.0f;
const F32 MAX_INVENTORY_WAIT_TIME = 30.0f;
const F32 MAX_ASSET_WAIT_TIME = 60.0f;
-static void updateProgress(const std::string message);
-
// static
-void FSExport::onIdle(void* user_data)
+void FSFloaterObjectExport::onIdle(void* user_data)
{
- FSExport* self = (FSExport*)user_data;
+ FSFloaterObjectExport* self = (FSFloaterObjectExport*)user_data;
self->onIdle();
}
-void FSExport::onIdle()
+void FSFloaterObjectExport::onIdle()
{
switch(mExportState)
{
@@ -97,6 +97,7 @@ void FSExport::onIdle()
{
mWaitTimer.start();
mLastRequest = mInventoryRequests.size();
+ updateTitleProgress(INVENTORY_DOWNLOAD);
}
else if (mWaitTimer.getElapsedTimeF32() > MAX_INVENTORY_WAIT_TIME)
{
@@ -107,9 +108,6 @@ void FSExport::onIdle()
object->dirtyInventory();
object->requestInventory();
- LLStringUtil::format_map_t args;
- args["ITEM"] = (*iter).asString();
- updateProgress(formatString(LLTrans::getString("export_rerequesting_inventory"), args));
LL_DEBUGS("export") << "re-requested inventory of " << (*iter).asString() << LL_ENDL;
}
}
@@ -130,6 +128,7 @@ void FSExport::onIdle()
{
mWaitTimer.start();
mLastRequest = mAssetRequests.size();
+ updateTitleProgress(ASSET_DOWNLOAD);
}
else if (mWaitTimer.getElapsedTimeF32() > MAX_ASSET_WAIT_TIME)
{
@@ -158,21 +157,22 @@ void FSExport::onIdle()
mWaitTimer.stop();
llofstream file;
- file.open(mFileName, std::ios_base::out | std::ios_base::binary);
- std::string zip_data = zip_llsd(mFile);
+ file.open(mFilename, std::ios_base::out | std::ios_base::binary);
+ std::string zip_data = zip_llsd(mManifest);
file.write(zip_data.data(), zip_data.size());
file.close();
- LL_DEBUGS("export") << "Export finished and written to " << mFileName << LL_ENDL;
+ LL_DEBUGS("export") << "Export finished and written to " << mFilename << LL_ENDL;
- updateProgress(LLTrans::getString("export_finished"));
LLSD args;
- args["FILENAME"] = mFileName;
+ args["FILENAME"] = mFilename;
LLNotificationsUtil::add("ExportFinished", args);
+ closeFloater();
}
else if (mLastRequest != mRequestedTexture.size())
{
mWaitTimer.start();
mLastRequest = mRequestedTexture.size();
+ updateTitleProgress(TEXTURE_DOWNLOAD);
}
else if (mWaitTimer.getElapsedTimeF32() > MAX_TEXTURE_WAIT_TIME)
{
@@ -183,11 +183,8 @@ void FSExport::onIdle()
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_id, FTT_DEFAULT, MIPMAP_TRUE);
image->setBoostLevel(LLViewerTexture::BOOST_MAX_LEVEL);
image->forceToSaveRawImage(0);
- image->setLoadedCallback(FSExport::onImageLoaded, 0, TRUE, FALSE, this, &mCallbackTextureList);
-
- LLStringUtil::format_map_t args;
- args["ITEM"] = texture_id.asString();
- updateProgress(formatString(LLTrans::getString("export_rerequesting_texture"), args));
+ image->setLoadedCallback(FSFloaterObjectExport::onImageLoaded, 0, TRUE, FALSE, this, &mCallbackTextureList);
+
LL_DEBUGS("export") << "re-requested texture " << texture_id.asString() << LL_ENDL;
}
}
@@ -197,32 +194,62 @@ void FSExport::onIdle()
}
}
-void FSExport::exportSelection()
+FSFloaterObjectExport::FSFloaterObjectExport(const LLSD& key)
+: LLFloater(key),
+mTotal(0),
+mIncluded(0),
+mNumTextures(0),
+mNumExportableTextures(0)
{
- LLObjectSelectionHandle selection = LLSelectMgr::instance().getSelection();
- if (!selection)
+ addSelectedObjects();
+}
+
+FSFloaterObjectExport::~FSFloaterObjectExport()
+{
+ if (gIdleCallbacks.containsFunction(FSFloaterObjectExport::onIdle, this))
+ {
+ gIdleCallbacks.deleteFunction(FSFloaterObjectExport::onIdle, this);
+ }
+}
+
+BOOL FSFloaterObjectExport::postBuild()
+{
+ childSetTextArg("exportable_prims", "[COUNT]", llformat("%d", mIncluded));
+ childSetTextArg("exportable_prims", "[TOTAL]", llformat("%d", mTotal));
+ childSetTextArg("exportable_textures", "[COUNT]", llformat("%d", mNumExportableTextures));
+ childSetTextArg("exportable_textures", "[TOTAL]", llformat("%d", mNumTextures));
+
+ mObjectList = getChild("selected_objects");
+ mExportBtn = getChild("export_btn");
+ if (mExportBtn)
+ mExportBtn->setCommitCallback(boost::bind(&FSFloaterObjectExport::onClickExport, this));
+
+ LLUIString title = getString("title_floater");
+ title.setArg("[OBJECT]", mObjectName);
+ setTitle(title);
+ populateObjectList();
+ addTexturePreview();
+
+ return TRUE;
+}
+
+bool FSFloaterObjectExport::exportSelection()
+{
+ if (!mSelection)
{
LL_WARNS("export") << "Nothing selected; Bailing!" << LL_ENDL;
- return;
+ return false;
}
- LLObjectSelection::valid_root_iterator iter = selection->valid_root_begin();
+ LLObjectSelection::valid_root_iterator iter = mSelection->valid_root_begin();
LLSelectNode* node = *iter;
if (!node)
{
LL_WARNS("export") << "No node selected; Bailing!" << LL_ENDL;
- return;
+ return false;
}
-
- LLFilePicker& file_picker = LLFilePicker::instance();
- if(!file_picker.getSaveFile(LLFilePicker::FFSAVE_EXPORT, LLDir::getScrubbedFileName(node->mName + ".oxp")))
- {
- llinfos << "User closed the filepicker, aborting export!" << llendl;
- return;
- }
- mFileName = file_picker.getFirstFile();
- mFilePath = gDirUtilp->getDirName(mFileName);
+ mFilePath = gDirUtilp->getDirName(mFilename);
- mFile.clear();
+ mManifest.clear();
mRequestedTexture.clear();
mExported = false;
@@ -230,17 +257,23 @@ void FSExport::exportSelection()
mInventoryRequests.clear();
mAssetRequests.clear();
mTextureChecked.clear();
-
- mFile["format_version"] = 1;
- mFile["client"] = LLAppViewer::instance()->getSecondLifeTitle() + LLVersionInfo::getChannel();
- mFile["client_version"] = LLVersionInfo::getVersion();
- mFile["grid"] = LLGridManager::getInstance()->getGridLabel();
- LLFloaterReg::showInstance("fs_export");
- updateProgress(LLTrans::getString("export_started"));
-
- for ( ; iter != selection->valid_root_end(); ++iter)
+
+ std::string author = "Unknown";
+ if (gCacheName)
+ gCacheName->getFullName(gAgentID, author);
+ char buff[10];
+ time_t now = time(NULL);
+ strftime(buff, 10, "%Y-%m-%d", localtime(&now));
+ std::string date(buff, 10);
+ mManifest["format_version"] = OXP_FORMAT_VERSION;
+ mManifest["client"] = LLVersionInfo::getChannelAndVersion();
+ mManifest["creation_date"] = date;
+ mManifest["author"] = author;
+ mManifest["grid"] = LLGridManager::getInstance()->getGridLabel();
+
+ for ( ; iter != mSelection->valid_root_end(); ++iter)
{
- mFile["linkset"].append(getLinkSet((*iter)));
+ mManifest["linkset"].append(getLinkSet((*iter)));
}
if (mExported && !mAborted)
@@ -252,12 +285,13 @@ void FSExport::exportSelection()
}
else
{
- updateProgress(LLTrans::getString("export_nothing_exported"));
LL_WARNS("export") << "Nothing was exported. File not created." << LL_ENDL;
+ return false;
}
+ return true;
}
-LLSD FSExport::getLinkSet(LLSelectNode* node)
+LLSD FSFloaterObjectExport::getLinkSet(LLSelectNode* node)
{
LLSD linkset;
LLViewerObject* object = node->getObject();
@@ -280,7 +314,7 @@ LLSD FSExport::getLinkSet(LLSelectNode* node)
return linkset;
}
-void FSExport::addPrim(LLViewerObject* object, bool root)
+void FSFloaterObjectExport::addPrim(LLViewerObject* object, bool root)
{
LLSD prim;
LLUUID object_id = object->getID();
@@ -295,49 +329,9 @@ void FSExport::addPrim(LLViewerObject* object, bool root)
return (node->getObject() && node->getObject()->mID == mID);
}
} func(object_id);
+
LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(&func);
- if (node)
- {
- if ((LLGridManager::getInstance()->isInSecondLife())
- && object->permYouOwner()
- && (gAgentID == node->mPermissions->getCreator() || megaPrimCheck(node->mPermissions->getCreator(), object)))
- {
- default_prim = false;
- }
-#ifdef OPENSIM
- if (LLGridManager::getInstance()->isInOpenSim())
- {
- LLViewerRegion* region = gAgent.getRegion();
- if (region && region->regionSupportsExport() == LLViewerRegion::EXPORT_ALLOWED)
- {
- default_prim = !node->mPermissions->allowExportBy(gAgent.getID());
- }
- else if (region && region->regionSupportsExport() == LLViewerRegion::EXPORT_DENIED)
- {
- // Only your own creations if this is explicitly set
- default_prim = (!(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
- {
- default_prim = (!(object->permYouOwner()
- && object->permModify()
- && object->permCopy()
- && object->permTransfer()));
- }
- }
-#endif
- }
- else
- {
- LL_WARNS("export") << "LLSelect node for " << object_id.asString() << " not found. Using default prim instead." << LL_ENDL;
- LLStringUtil::format_map_t args;
- args["OBJECT"] = object_id.asString();
- updateProgress(formatString(LLTrans::getString("export_node_not_found"), args));
- default_prim = true;
- }
+ default_prim = (!FSExportPermsCheck::canExportNode(node));
if (root)
{
@@ -357,10 +351,6 @@ void FSExport::addPrim(LLViewerObject* object, bool root)
if (default_prim)
{
- LLStringUtil::format_map_t args;
- args["OBJECT"] = object_id.asString();
- updateProgress(formatString(LLTrans::getString("export_failed_export_check"), args));
-
LL_DEBUGS("export") << object_id.asString() << " failed export check. Using default prim" << LL_ENDL;
prim["flags"] = ll_sd_from_U32((U32)0);
prim["volume"]["path"] = LLPathParams().asLLSD();
@@ -395,7 +385,6 @@ void FSExport::addPrim(LLViewerObject* object, bool root)
{
if (!mAborted)
{
- updateProgress(LLTrans::getString("export_fail_no_mesh"));
mAborted = true;
}
return;
@@ -538,20 +527,23 @@ void FSExport::addPrim(LLViewerObject* object, bool root)
prim["touch_name"] = node->mTouchName;
prim["sit_name"] = node->mSitName;
- mInventoryRequests.push_back(object_id);
- object->registerInventoryListener(this, NULL);
- object->dirtyInventory();
- object->requestInventory();
+ static LLCachedControl sExportContents(gSavedSettings, "FSExportContents");
+ if (sExportContents)
+ {
+ mInventoryRequests.push_back(object_id);
+ object->registerInventoryListener(this, NULL);
+ object->dirtyInventory();
+ object->requestInventory();
+ }
}
- mFile["prim"][object_id.asString()] = prim;
+ mManifest["prim"][object_id.asString()] = prim;
}
-bool FSExport::exportTexture(const LLUUID& texture_id)
+bool FSFloaterObjectExport::exportTexture(const LLUUID& texture_id)
{
if(texture_id.isNull())
{
- updateProgress(LLTrans::getString("export_failed_null_texture"));
LL_WARNS("export") << "Attempted to export NULL texture." << LL_ENDL;
return false;
}
@@ -564,12 +556,12 @@ bool FSExport::exportTexture(const LLUUID& texture_id)
if (gAssetStorage->mStaticVFS->getExists(texture_id, LLAssetType::AT_TEXTURE))
{
LL_DEBUGS("export") << "Texture " << texture_id.asString() << " is local static." << LL_ENDL;
- // no need to save the texture data as the viewer allready has it in a local file.
+ // no need to save the texture data as the viewer already has it in a local file.
mTextureChecked[texture_id] = true;
return true;
}
- //TODO: check for local file static texture. The above will only get the static texture in the static db, not indevitial texture files.
+ //TODO: check for local file static texture. The above will only get the static texture in the static db, not individual textures.
LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(texture_id);
bool texture_export = false;
@@ -590,105 +582,53 @@ bool FSExport::exportTexture(const LLUUID& texture_id)
if (texture_export)
{
- assetCheck(texture_id, name, description);
+ FSExportPermsCheck::canExportAsset(texture_id, &name, &description);
}
else
{
- texture_export = assetCheck(texture_id, name, description);
+ texture_export = FSExportPermsCheck::canExportAsset(texture_id, &name, &description);
}
mTextureChecked[texture_id] = texture_export;
- LLStringUtil::format_map_t args;
- args["ITEM"] = name;
-
if (!texture_export)
{
- updateProgress(formatString(LLTrans::getString("export_asset_failed_export_check"), args));
-
LL_DEBUGS("export") << "Texture " << texture_id << " failed export check." << LL_ENDL;
return false;
}
LL_DEBUGS("export") << "Loading image texture " << texture_id << LL_ENDL;
- updateProgress(formatString(LLTrans::getString("export_loading_texture"), args));
mRequestedTexture[texture_id].name = name;
mRequestedTexture[texture_id].description = description;
LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(texture_id, FTT_DEFAULT, MIPMAP_TRUE);
image->setBoostLevel(LLViewerTexture::BOOST_MAX_LEVEL);
image->forceToSaveRawImage(0);
- image->setLoadedCallback(FSExport::onImageLoaded, 0, TRUE, FALSE, this, &mCallbackTextureList);
+ image->setLoadedCallback(FSFloaterObjectExport::onImageLoaded, 0, TRUE, FALSE, this, &mCallbackTextureList);
return true;
}
// static
-void FSExport::onImageLoaded(BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
+void FSFloaterObjectExport::onImageLoaded(BOOL success, LLViewerFetchedTexture* src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata)
{
if(final && success)
{
- const LLUUID& texture_id = src_vi->getID();
- LLImageJ2C* mFormattedImage = new LLImageJ2C;
- FSExportCacheReadResponder* responder = new FSExportCacheReadResponder(texture_id, mFormattedImage);
- LLAppViewer::getTextureCache()->readFromCache(texture_id, LLWorkerThread::PRIORITY_HIGH, 0, 999999, responder);
- LL_DEBUGS("export") << "Fetching " << texture_id << " from the TextureCache" << LL_ENDL;
+ // *HACK ALERT: I'm lazy so I moved this to a non-static member function.
+ FSFloaterObjectExport* parent = (FSFloaterObjectExport *)userdata;
+ parent->fetchTextureFromCache(src_vi);
}
}
-
-FSExportCacheReadResponder::FSExportCacheReadResponder(const LLUUID& id, LLImageFormatted* image) :
- mFormattedImage(image),
- mID(id)
+void FSFloaterObjectExport::fetchTextureFromCache(LLViewerFetchedTexture* src_vi)
{
- setImage(image);
+ const LLUUID& texture_id = src_vi->getID();
+ LLImageJ2C* mFormattedImage = new LLImageJ2C;
+ FSFloaterObjectExport::FSExportCacheReadResponder* responder = new FSFloaterObjectExport::FSExportCacheReadResponder(texture_id, mFormattedImage, this);
+ LLAppViewer::getTextureCache()->readFromCache(texture_id, LLWorkerThread::PRIORITY_HIGH, 0, 999999, responder);
+ LL_DEBUGS("export") << "Fetching " << texture_id << " from the TextureCache" << LL_ENDL;
}
-void FSExportCacheReadResponder::setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal)
-{
- if (imageformat != IMG_CODEC_J2C)
- {
- LL_WARNS("export") << "Texture " << mID << " is not formatted as J2C." << LL_ENDL;
- }
-
- if (mFormattedImage.notNull())
- {
- mFormattedImage->appendData(data, datasize);
- }
- else
- {
- mFormattedImage = LLImageFormatted::createFromType(imageformat);
- mFormattedImage->setData(data, datasize);
- }
- mImageSize = imagesize;
- mImageLocal = imagelocal;
-}
-
-void FSExportCacheReadResponder::completed(bool success)
-{
- LLStringUtil::format_map_t args;
- args["TEXTURE"] = mID.asString();
- if (success && mFormattedImage.notNull() && mImageSize > 0)
- {
- LL_DEBUGS("export") << "SUCCESS getting texture " << mID << LL_ENDL;
- FSExport::getInstance()->saveFormattedImage(mFormattedImage, mID);
- }
- else
- {
- //NOTE: we can get here due to trying to fetch a static local texture
- // do nothing spiachel as importing static local texture just needs an UUID only.
- if (!success)
- {
- LL_WARNS("export") << "FAILED to get texture " << mID << LL_ENDL;
- }
- if (mFormattedImage.isNull())
- {
- LL_WARNS("export") << "FAILED: NULL texture " << mID << LL_ENDL;
- }
- FSExport::getInstance()->removeRequestedTexture(mID);
- }
-}
-
-void FSExport::removeRequestedTexture(LLUUID texture_id)
+void FSFloaterObjectExport::removeRequestedTexture(LLUUID texture_id)
{
if (mRequestedTexture.count(texture_id) != 0)
{
@@ -696,42 +636,21 @@ void FSExport::removeRequestedTexture(LLUUID texture_id)
}
}
-void FSExport::saveFormattedImage(LLPointer mFormattedImage, LLUUID id)
+void FSFloaterObjectExport::saveFormattedImage(LLPointer mFormattedImage, LLUUID id)
{
std::stringstream texture_str;
texture_str.write((const char*) mFormattedImage->getData(), mFormattedImage->getDataSize());
std::string str = texture_str.str();
- mFile["asset"][id.asString()]["name"] = mRequestedTexture[id].name;
- mFile["asset"][id.asString()]["description"] = mRequestedTexture[id].description;
- mFile["asset"][id.asString()]["type"] = LLAssetType::lookup(LLAssetType::AT_TEXTURE);
- mFile["asset"][id.asString()]["data"] = LLSD::Binary(str.begin(),str.end());
-
- LLStringUtil::format_map_t args;
- args["TEXTURE"] = mRequestedTexture[id].name;
- updateProgress(formatString(LLTrans::getString("export_saving_texture"), args));
+ mManifest["asset"][id.asString()]["name"] = mRequestedTexture[id].name;
+ mManifest["asset"][id.asString()]["description"] = mRequestedTexture[id].description;
+ mManifest["asset"][id.asString()]["type"] = LLAssetType::lookup(LLAssetType::AT_TEXTURE);
+ mManifest["asset"][id.asString()]["data"] = LLSD::Binary(str.begin(),str.end());
removeRequestedTexture(id);
}
-bool FSExport::megaPrimCheck(LLUUID creator, LLViewerObject* object)
-{
- F32 max_object_size = LLWorld::getInstance()->getRegionMaxPrimScale();
- LLVector3 vec = object->getScale();
- if (!(vec.mV[VX] > max_object_size || vec.mV[VY] > max_object_size || vec.mV[VZ] > max_object_size))
- {
- return false;
- }
-
- if (creator == LLUUID("7ffd02d0-12f4-48b4-9640-695708fd4ae4")) // Zwagoth Klaar
- {
- return true;
- }
-
- return false;
-}
-
-bool FSExport::defaultTextureCheck(const LLUUID asset_id)
+bool FSFloaterObjectExport::defaultTextureCheck(const LLUUID asset_id)
{
if (asset_id == LL_DEFAULT_WOOD_UUID ||
asset_id == LL_DEFAULT_STONE_UUID ||
@@ -755,62 +674,7 @@ bool FSExport::defaultTextureCheck(const LLUUID asset_id)
return false;
}
-bool FSExport::assetCheck(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;
-}
-
-void FSExport::inventoryChanged(LLViewerObject* object, LLInventoryObject::object_list_t* inventory, S32 serial_num, void* user_data)
+void FSFloaterObjectExport::inventoryChanged(LLViewerObject* object, LLInventoryObject::object_list_t* inventory, S32 serial_num, void* user_data)
{
uuid_vec_t::iterator v_iter = std::find(mInventoryRequests.begin(), mInventoryRequests.end(), object->getID());
if (v_iter != mInventoryRequests.end())
@@ -819,7 +683,7 @@ void FSExport::inventoryChanged(LLViewerObject* object, LLInventoryObject::objec
mInventoryRequests.erase(v_iter);
}
- LLSD& prim = mFile["prim"][object->getID().asString()];
+ LLSD& prim = mManifest["prim"][object->getID().asString()];
for (LLInventoryObject::object_list_t::const_iterator iter = inventory->begin(); iter != inventory->end(); ++iter)
{
LLInventoryItem* item = dynamic_cast(iter->get());
@@ -860,9 +724,6 @@ void FSExport::inventoryChanged(LLViewerObject* object, LLInventoryObject::objec
// Only complain if we're trying to export a non-NULL item and fail
if (!item->getUUID().isNull())
{
- LLStringUtil::format_map_t args;
- args["ITEM"] = item->getName();
- updateProgress(formatString(LLTrans::getString("export_asset_failed_export_check"), args));
LL_DEBUGS("export") << "Item " << item->getName() << ", UUID " << item->getUUID() << " failed export check." << LL_ENDL;
}
continue;
@@ -871,15 +732,12 @@ void FSExport::inventoryChanged(LLViewerObject* object, LLInventoryObject::objec
if (item->getType() == LLAssetType::AT_NONE || item->getType() == LLAssetType::AT_OBJECT)
{
// currentelly not exportable
- LLStringUtil::format_map_t args;
- args["ITEM"] = item->getName();
- updateProgress(formatString(LLTrans::getString("export_item_not_exportable"), args));
LL_DEBUGS("export") << "Skipping " << LLAssetType::lookup(item->getType()) << " item " << item->getName() << LL_ENDL;
continue;
}
prim["content"].append(item->getUUID());
- mFile["inventory"][item->getUUID().asString()] = ll_create_sd_from_inventory_item(item);
+ mManifest["inventory"][item->getUUID().asString()] = ll_create_sd_from_inventory_item(item);
if (item->getAssetUUID().isNull() && item->getType() == LLAssetType::AT_NOTECARD)
{
@@ -887,24 +745,21 @@ void FSExport::inventoryChanged(LLViewerObject* object, LLInventoryObject::objec
// Blank Notecard item can have NULL asset ID.
// Generate a new UUID and save as an empty asset.
LLUUID asset_uuid = LLUUID::generateNewID();
- mFile["inventory"][item->getUUID().asString()]["asset_id"] = asset_uuid;
+ mManifest["inventory"][item->getUUID().asString()]["asset_id"] = asset_uuid;
- mFile["asset"][asset_uuid.asString()]["name"] = item->getName();
- mFile["asset"][asset_uuid.asString()]["description"] = item->getDescription();
- mFile["asset"][asset_uuid.asString()]["type"] = LLAssetType::lookup(item->getType());
+ mManifest["asset"][asset_uuid.asString()]["name"] = item->getName();
+ mManifest["asset"][asset_uuid.asString()]["description"] = item->getDescription();
+ mManifest["asset"][asset_uuid.asString()]["type"] = LLAssetType::lookup(item->getType());
LLNotecard nc(255); //don't need to allocate default size of 65536
std::stringstream out_stream;
nc.exportStream(out_stream);
std::string out_string = out_stream.str();
std::vector buffer(out_string.begin(), out_string.end());
- mFile["asset"][asset_uuid.asString()]["data"] = buffer;
+ mManifest["asset"][asset_uuid.asString()]["data"] = buffer;
}
else
{
- LLStringUtil::format_map_t args;
- args["ITEM"] = item->getName();
- updateProgress(formatString(LLTrans::getString("export_requesting_asset"), args));
LL_DEBUGS("export") << "Requesting asset " << item->getAssetUUID() << " for item " << item->getUUID() << LL_ENDL;
mAssetRequests.push_back(item->getUUID());
FSAssetResourceData* data = new FSAssetResourceData;
@@ -937,48 +792,39 @@ void FSExport::inventoryChanged(LLViewerObject* object, LLInventoryObject::objec
}
}
}
-
object->removeInventoryListener(this);
}
// static
-void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status)
+void FSFloaterObjectExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status)
{
FSAssetResourceData* data = (FSAssetResourceData*)user_data;
- FSExport* self = (FSExport*)data->user_data;
+ FSFloaterObjectExport* self = (FSFloaterObjectExport*)data->user_data;
LLUUID item_uuid = data->uuid;
self->removeRequestedAsset(item_uuid);
if (status != 0)
{
- LLStringUtil::format_map_t args;
- args["ITEM"] = asset_uuid.asString();
- args["STATUS"] = llformat("%d",status);
- args["EXT_STATUS"] = llformat("%d",ext_status);
- updateProgress(formatString(LLTrans::getString("export_failed_fetch"), args));
LL_WARNS("export") << "Problem fetching asset: " << asset_uuid << " " << status << " " << ext_status << LL_ENDL;
delete data;
return;
}
- LLStringUtil::format_map_t args;
- args["ITEM"] = data->name;
- updateProgress(formatString(LLTrans::getString("export_saving_asset"), args));
LL_DEBUGS("export") << "Saving asset " << asset_uuid.asString() << " of item " << item_uuid.asString() << LL_ENDL;
LLVFile file(vfs, asset_uuid, type);
S32 file_length = file.getSize();
std::vector buffer(file_length);
file.read(&buffer[0], file_length);
- self->mFile["asset"][asset_uuid.asString()]["name"] = data->name;
- self->mFile["asset"][asset_uuid.asString()]["description"] = data->description;
- self->mFile["asset"][asset_uuid.asString()]["type"] = LLAssetType::lookup(type);
- self->mFile["asset"][asset_uuid.asString()]["data"] = buffer;
+ self->mManifest["asset"][asset_uuid.asString()]["name"] = data->name;
+ self->mManifest["asset"][asset_uuid.asString()]["description"] = data->description;
+ self->mManifest["asset"][asset_uuid.asString()]["type"] = LLAssetType::lookup(type);
+ self->mManifest["asset"][asset_uuid.asString()]["data"] = buffer;
- if (self->mFile["inventory"].has(item_uuid.asString()))
+ if (self->mManifest["inventory"].has(item_uuid.asString()))
{
- if (self->mFile["inventory"][item_uuid.asString()]["asset_id"].asUUID().isNull())
+ if (self->mManifest["inventory"][item_uuid.asString()]["asset_id"].asUUID().isNull())
{
- self->mFile["inventory"][item_uuid.asString()]["asset_id"] = asset_uuid;
+ self->mManifest["inventory"][item_uuid.asString()]["asset_id"] = asset_uuid;
}
}
@@ -1013,9 +859,6 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
LLDataPackerAsciiBuffer dp((char*)&buffer[0], file_length+1);
if (!gesture->deserialize(dp))
{
- LLStringUtil::format_map_t args;
- args["ITEM"] = asset_uuid.asString();
- updateProgress(formatString(LLTrans::getString("export_failed_to_load"), args));
LL_WARNS("export") << "Unable to load gesture " << asset_uuid << LL_ENDL;
break;
}
@@ -1032,11 +875,8 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
case STEP_ANIMATION:
{
LLGestureStepAnimation* anim_step = (LLGestureStepAnimation*)step;
- if (!self->assetCheck(anim_step->mAnimAssetID, name, description))
+ if (!FSExportPermsCheck::canExportAsset(anim_step->mAnimAssetID, &name, &description))
{
- LLStringUtil::format_map_t args;
- args["ITEM"] = data->name;
- updateProgress(formatString(LLTrans::getString("export_asset_failed_export_check"), args));
LL_DEBUGS("export") << "Asset in gesture " << data->name << " failed export check." << LL_ENDL;
break;
}
@@ -1045,10 +885,7 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
anim_data->name = anim_step->mAnimName;
anim_data->user_data = self;
anim_data->uuid = anim_step->mAnimAssetID;
-
- LLStringUtil::format_map_t args;
- args["ITEM"] = anim_step->mAnimAssetID.asString();
- updateProgress(formatString(LLTrans::getString("export_requesting_asset"), args));
+
LL_DEBUGS("export") << "Requesting animation asset " << anim_step->mAnimAssetID.asString() << LL_ENDL;
self->mAssetRequests.push_back(anim_step->mAnimAssetID);
gAssetStorage->getAssetData(anim_step->mAnimAssetID,
@@ -1061,11 +898,8 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
case STEP_SOUND:
{
LLGestureStepSound* sound_step = (LLGestureStepSound*)step;
- if (!self->assetCheck(sound_step->mSoundAssetID, name, description))
+ if (!FSExportPermsCheck::canExportAsset(sound_step->mSoundAssetID, &name, &description))
{
- LLStringUtil::format_map_t args;
- args["ITEM"] = data->name;
- updateProgress(formatString(LLTrans::getString("export_asset_failed_export_check"), args));
LL_DEBUGS("export") << "Asset in gesture " << data->name << " failed export check." << LL_ENDL;
break;
}
@@ -1074,10 +908,7 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
sound_data->name = sound_step->mSoundName;
sound_data->user_data = self;
sound_data->uuid = sound_step->mSoundAssetID;
-
- LLStringUtil::format_map_t args;
- args["ITEM"] = sound_step->mSoundAssetID.asString();
- updateProgress(formatString(LLTrans::getString("export_requesting_asset"), args));
+
LL_DEBUGS("export") << "Requesting sound asset " << sound_step->mSoundAssetID.asString() << LL_ENDL;
self->mAssetRequests.push_back(sound_step->mSoundAssetID);
gAssetStorage->getAssetData(sound_step->mSoundAssetID,
@@ -1101,7 +932,7 @@ void FSExport::onLoadComplete(LLVFS* vfs, const LLUUID& asset_uuid, LLAssetType:
delete data;
}
-void FSExport::removeRequestedAsset(LLUUID asset_uuid)
+void FSFloaterObjectExport::removeRequestedAsset(LLUUID asset_uuid)
{
uuid_vec_t::iterator iter = std::find(mAssetRequests.begin(), mAssetRequests.end(), asset_uuid);
if (iter != mAssetRequests.end())
@@ -1111,53 +942,283 @@ void FSExport::removeRequestedAsset(LLUUID asset_uuid)
}
}
-// static
-void updateProgress(const std::string message)
+void FSFloaterObjectExport::addObject(const LLViewerObject* prim, const std::string name)
{
- FSFloaterObjectExport* export_floater = LLFloaterReg::findTypedInstance("fs_export");
- if (export_floater)
- export_floater->updateProgress(message);
+ mObjects.push_back(std::pair((LLViewerObject*)prim, name));
}
-//-----------------------------------------------------
-// FSFloaterObjectExport
-//-----------------------------------------------------
-
-FSFloaterObjectExport::FSFloaterObjectExport(const LLSD& key)
-: LLFloater(key),
- mOutputList(NULL)
+// *TODO: I know it's really lame to tack this in here, maybe someday it can be integrated properly.
+void FSFloaterObjectExport::updateTextureInfo()
{
-}
-
-// virtual
-FSFloaterObjectExport::~FSFloaterObjectExport()
-{
-}
-
-// virtual
-BOOL FSFloaterObjectExport::postBuild()
-{
- mOutputList = getChild("export_output");
- if (mOutputList)
- mOutputList->deleteAllItems();
- childSetAction("close_btn", boost::bind(&FSFloaterObjectExport::onCloseBtn, this));
- return TRUE;
-}
-
-void FSFloaterObjectExport::onCloseBtn()
-{
- mOutputList->deleteAllItems();
- closeFloater();
-}
-
-void FSFloaterObjectExport::updateProgress(const std::string message)
-{
- if (mOutputList)
+ mTextures.clear();
+ //mTextureNames.clear();
+
+ for (obj_info_t::iterator obj_iter = mObjects.begin(); obj_iter != mObjects.end(); ++obj_iter)
{
- LLSD row;
- row["columns"][0]["value"] = message;
- mOutputList->addElement(row);
- mOutputList->selectItemByLabel(message);
- mOutputList->scrollToShowSelected();
+ LLViewerObject* obj = obj_iter->first;
+ S32 num_faces = obj->getVolume()->getNumVolumeFaces();
+ for (S32 face_num = 0; face_num < num_faces; ++face_num)
+ {
+ LLTextureEntry* te = obj->getTE(face_num);
+ const LLUUID id = te->getID();
+
+ 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;
+ 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 (exportable)
+ {
+ //std::string safe_name = gDirUtilp->getScrubbedFileName(name);
+ //std::replace(safe_name.begin(), safe_name.end(), ' ', '_');
+ mTextureNames.push_back(name);
+ }
+ else
+ {
+ mTextureNames.push_back(std::string());
+ }
+ }
+ }
+}
+
+void FSFloaterObjectExport::updateTitleProgress(FSExportState state)
+{
+ LLUIString title;
+ switch (state)
+ {
+ case INVENTORY_DOWNLOAD:
+ {
+ title = getString("title_inventory");
+ break;
+ }
+ case ASSET_DOWNLOAD:
+ {
+ title = getString("title_assets");
+ break;
+ }
+ case TEXTURE_DOWNLOAD:
+ {
+ title = getString("title_textures");
+ break;
+ }
+ case IDLE:
+ default:
+ LL_WARNS("export") << "Unhandled case: " << state << LL_ENDL;
+ return;
+ }
+ LLSD args;
+ args["OBJECT"] = mObjectName;
+ title.setArgs(args);
+ setTitle(title);
+}
+
+void FSFloaterObjectExport::onClickExport()
+{
+ LLFilePicker& file_picker = LLFilePicker::instance();
+ if(!file_picker.getSaveFile(LLFilePicker::FFSAVE_EXPORT, LLDir::getScrubbedFileName(mObjectName + ".oxp")))
+ {
+ llinfos << "User closed the filepicker, aborting export!" << llendl;
+ return;
+ }
+ mFilename = file_picker.getFirstFile();
+
+ LLUIString title = getString("title_working");
+ title.setArg("[OBJECT]", mObjectName);
+ setTitle(title);
+
+ if (!exportSelection())
+ {
+ LLNotificationsUtil::add("ExportFailed");
+ closeFloater();
+ }
+}
+
+void FSFloaterObjectExport::populateObjectList()
+{
+ if (mObjectList && !mObjects.empty())
+ {
+ for (obj_info_t::iterator obj_iter = mObjects.begin(); obj_iter != mObjects.end(); ++obj_iter)
+ {
+ LLSD element;
+ element["columns"][0]["column"] = "icon";
+ element["columns"][0]["type"] = "icon";
+ element["columns"][0]["value"] = "Inv_Object";
+ element["columns"][1]["column"] = "name";
+ element["columns"][1]["value"] = obj_iter->second;
+ mObjectList->addElement(element, ADD_BOTTOM);
+
+ }
+ }
+}
+
+// Copypasta from DAE Export. :o
+void FSFloaterObjectExport::addSelectedObjects()
+{
+ if ((mSelection = LLSelectMgr::getInstance()->getSelection()))
+ {
+ mObjectName = mSelection->getFirstRootNode()->mName;
+ for (LLObjectSelection::iterator iter = mSelection->begin(); iter != mSelection->end(); ++iter)
+ {
+ LLSelectNode* node = *iter;
+ mTotal++;
+ if (!node->getObject()->getVolume() || !FSExportPermsCheck::canExportNode(node)) continue;
+ mIncluded++;
+ addObject(node->getObject(), node->mName);
+ }
+
+ if (mObjects.empty())
+ {
+ LL_WARNS("export") << "Nothing selected passed permissions checks!" << LL_ENDL;
+ LLNotificationsUtil::add("ExportFailed");
+ closeFloater();
+ return;
+ }
+
+ updateTextureInfo();
+ mNumTextures = mTextures.size();
+ mNumExportableTextures = getNumExportableTextures();
+ }
+ else
+ {
+ LL_WARNS("export") << "Nothing selected!" << LL_ENDL;
+ LLNotificationsUtil::add("ExportFailed");
+ closeFloater();
+ }
+}
+
+S32 FSFloaterObjectExport::getNumExportableTextures()
+{
+ S32 res = 0;
+ for (string_list_t::const_iterator t = mTextureNames.begin(); t != mTextureNames.end(); ++t)
+ {
+ std::string name = *t;
+ if (!name.empty())
+ {
+ ++res;
+ }
+ }
+
+ return res;
+}
+
+void FSFloaterObjectExport::addTexturePreview()
+{
+ S32 num_text = mNumExportableTextures;
+ if (num_text == 0) return;
+ S32 img_width = 100;
+ S32 img_height = img_width + 15;
+ S32 panel_height = (num_text / 2 + 1) * (img_height) + 10;
+ LLRect pr(0, panel_height, 230, 0);
+ LLPanel::Params pp;
+ pp.rect(pr);
+ pp.name("textures_panel");
+ pp.layout("topleft");
+ pp.enabled(false);
+ LLPanel* texture_panel = LLUICtrlFactory::create(pp);
+ getChild("selected_textures")->addChild(texture_panel);
+ S32 img_nr = 0;
+ for (S32 i=0; i < mTextures.size(); i++)
+ {
+ if (mTextureNames[i].empty()) continue;
+
+ S32 left = 8 + (img_nr % 2) * (img_width + 13);
+ S32 bottom = panel_height - (10 + (img_nr / 2 + 1) * (img_height));
+ LLRect r(left, bottom + img_height, left + img_width, bottom);
+ LLTextureCtrl::Params p;
+ p.rect(r);
+ p.layout("topleft");
+ p.image_id(mTextures[i]);
+ p.tool_tip(mTextureNames[i]);
+ LLTextureCtrl* texture_block = LLUICtrlFactory::create(p);
+ texture_panel->addChild(texture_block);
+ img_nr++;
+ }
+ // Put 'em in the other list too.
+ if (mObjectList && !mTextureNames.empty())
+ {
+ for (string_list_t::iterator iter = mTextureNames.begin(); iter != mTextureNames.end(); ++iter)
+ {
+ LLSD element;
+ element["columns"][0]["column"] = "icon";
+ element["columns"][0]["type"] = "icon";
+ element["columns"][0]["value"] = "Inv_Texture";
+ element["columns"][1]["column"] = "name";
+ element["columns"][1]["value"] = (*iter);
+ mObjectList->addElement(element, ADD_BOTTOM);
+
+ }
+ }
+}
+
+///////////////////////////////////////////
+// FSExportCacheReadResponder
+
+FSFloaterObjectExport::FSExportCacheReadResponder::FSExportCacheReadResponder(const LLUUID& id, LLImageFormatted* image, FSFloaterObjectExport* parent)
+: mFormattedImage(image),
+mID(id),
+mParent(parent)
+{
+ setImage(image);
+}
+
+void FSFloaterObjectExport::FSExportCacheReadResponder::setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal)
+{
+ if (imageformat != IMG_CODEC_J2C)
+ {
+ LL_WARNS("export") << "Texture " << mID << " is not formatted as J2C." << LL_ENDL;
+ }
+
+ if (mFormattedImage.notNull())
+ {
+ mFormattedImage->appendData(data, datasize);
+ }
+ else
+ {
+ mFormattedImage = LLImageFormatted::createFromType(imageformat);
+ mFormattedImage->setData(data, datasize);
+ }
+ mImageSize = imagesize;
+ mImageLocal = imagelocal;
+}
+
+void FSFloaterObjectExport::FSExportCacheReadResponder::completed(bool success)
+{
+ if (success && mFormattedImage.notNull() && mImageSize > 0)
+ {
+ LL_DEBUGS("export") << "SUCCESS getting texture " << mID << LL_ENDL;
+ if (mParent)
+ mParent->saveFormattedImage(mFormattedImage, mID);
+ }
+ else
+ {
+ /// NOTE: we can get here due to trying to fetch a static local texture
+ /// do nothing special as importing static local texture just needs an UUID only.
+ if (!success)
+ {
+ LL_WARNS("export") << "FAILED to get texture " << mID << LL_ENDL;
+ }
+ if (mFormattedImage.isNull())
+ {
+ LL_WARNS("export") << "FAILED: NULL texture " << mID << LL_ENDL;
+ }
+ mParent->removeRequestedTexture(mID);
}
}
diff --git a/indra/newview/fsexport.h b/indra/newview/fsfloaterexport.h
similarity index 54%
rename from indra/newview/fsexport.h
rename to indra/newview/fsfloaterexport.h
index 245db63551..402c528e72 100644
--- a/indra/newview/fsexport.h
+++ b/indra/newview/fsfloaterexport.h
@@ -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
*
* 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, 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 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 > 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 mRequestedTexture;
- std::string mFileName;
+ std::map mTextureChecked;
std::string mFilePath;
LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList;
LLFrameTimer mWaitTimer;
S32 mLastRequest;
- std::map mTextureChecked;
bool mExported;
bool mAborted;
bool mExportError;
-
+
+ typedef std::vector id_list_t;
+ typedef std::vector 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 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 mFormattedImage;
+ LLUUID mID;
+ FSFloaterObjectExport* mParent;
+ };
};
#endif // FS_FSEXPORT_H
diff --git a/indra/newview/fsfloaterimport.cpp b/indra/newview/fsfloaterimport.cpp
index 14f893ec01..5d3d703803 100644
--- a/indra/newview/fsfloaterimport.cpp
+++ b/indra/newview/fsfloaterimport.cpp
@@ -64,23 +64,23 @@
#include "llvfile.h"
#include "llvfs.h"
#include "llvolumemessage.h"
+#include "fsexportperms.h"
#include "material_codes.h"
#include
#include
-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("temp_asset")->setVisible(FALSE);
getChild("temp_asset")->set(FALSE);
}
+ getChild("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("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("import_file")->setEnabled(TRUE);
+ getChild("import_btn")->setEnabled(TRUE);
getChild("do_not_attach")->setEnabled(TRUE);
getChild("region_position")->setEnabled(TRUE);
getChild("upload_asset")->setEnabled(TRUE);
}
else
{
- getChild("import_file")->setEnabled(FALSE);
+ getChild("import_btn")->setEnabled(FALSE);
getChild("do_not_attach")->setEnabled(FALSE);
getChild("region_position")->setEnabled(FALSE);
getChild("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 buffer = mFile["asset"][asset_id.asString()]["data"].asBinary();
+ std::vector 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("pick_file")->setEnabled(FALSE);
- getChild("import_file")->setEnabled(FALSE);
+ getChild("import_btn")->setEnabled(FALSE);
getChild("do_not_attach")->setEnabled(FALSE);
getChild("region_position")->setEnabled(FALSE);
getChild("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("pick_file")->setEnabled(TRUE);
- getChild("import_file")->setEnabled(TRUE);
+ getChild("import_btn")->setEnabled(TRUE);
getChild("do_not_attach")->setEnabled(TRUE);
getChild("region_position")->setEnabled(TRUE);
getChild("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("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("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("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("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 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 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("temp_asset")->get();
- if (tempary)
+ temporary = getChild("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("temp_asset")->get();
- if (tempary)
+ temporary = getChild("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("temp_asset")->get();
- if (tempary)
+ temporary = getChild("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")
{
diff --git a/indra/newview/fsfloaterimport.h b/indra/newview/fsfloaterimport.h
index 0e842278de..55bdb6a477 100644
--- a/indra/newview/fsfloaterimport.h
+++ b/indra/newview/fsfloaterimport.h
@@ -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
+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 mAssetMap;
BOOL mSavedSettingShowNewInventory;
+ boost::signals2::connection mObjectCreatedCallback;
struct FSInventoryQueue
{
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 83577ad051..7331350bff 100755
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -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"
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index ca8c1116db..707f7b595f 100755
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -136,7 +136,7 @@
// [/RLVa:KB]
#include "fslslbridge.h"
#include "fscommon.h"
-#include "fsexport.h"
+#include "fsfloaterexport.h"
#include "fscontactsfloater.h" // Display group list in contacts floater
#include "fspose.h" // 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;
}
};
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index cb5d5350d5..938c9a5d87 100755
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -640,6 +640,17 @@ class LLFileUploadBulk : public view_listener_t
}
};
+// 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;
+ }
+};
+//
+
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"); // Import linkset item
// "File.SaveTexture" moved to llpanelmaininventory so that it can be properly handled.
}
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 234d21ab7f..7237eb84dd 100755
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -226,6 +226,13 @@ void LLViewerObjectList::setUUIDAndLocal(const LLUUID &id,
S32 gFullObjectUpdates = 0;
S32 gTerseObjectUpdates = 0;
+// Object Import
+boost::signals2::connection LLViewerObjectList::setNewObjectCallback(new_object_callback_t cb)
+{
+ return mNewObjectSignal.connect(cb);
+}
+//
+
void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
void** user_data,
U32 i,
@@ -267,10 +274,10 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
// import support
bool import_handled = false;
bool own_full_perm = (objectp->permYouOwner() && objectp->permModify() && objectp->permTransfer() && objectp->permCopy());
- FSFloaterImport* floater_import = LLFloaterReg::getTypedInstance("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)
{
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 6518c25d09..f6ecf36c7a 100755
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -135,6 +135,13 @@ public:
void removeFromMap(LLViewerObject *objectp);
void clearDebugText();
+
+ // Import
+ typedef boost::function new_object_callback_t;
+ typedef boost::signals2::signal new_object_signal_t;
+ boost::signals2::connection setNewObjectCallback(new_object_callback_t cb);
+ new_object_signal_t mNewObjectSignal;
+ //
////////////////////////////////////////////
//
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index c28027c760..aef3696cd2 100755
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -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.
-
- Beginne Export...
-
-
- Export beendet.
-
-
- Der Export von Mesh wird derzeit nicht unterstützt. Export abgebrochen.
-
-
- Kein Export durchgeführt. Backup wurde nicht erstellt.
-
-
- LLSelect-Knoten für [OBJECT] gefunden. Verwende Standard-Prim.
-
-
- Berechtigungen für [OBJECT] unzureichend. Verwende Standard-Prim.
-
-
- Berechtigungen für [ITEM] unzureichend - übersprungen...
-
-
- Versuchter Export einer leeren Textur.
-
-
- Lade Textur [ITEM]...
-
-
- Textur [TEXTURE] erfolgreich gespeichert.
-
-
- Speichere [ITEM]...
-
-
- Fehler beim Laden von Textur [TEXTURE].
-
-
- Leere Textur [TEXTURE] empfangen.
-
-
- [ITEM] wird aktuell nicht vom Exporter unterstützt - übersprungen...
-
-
- [ITEM] konnte nicht geladen werden. (Status [STATUS] [EXT_STATUS])
-
-
- Fordere Asset [ITEM] an...
-
-
- Fordere Inventar von [ITEM] erneut an.
-
-
- Fordere Textur [ITEM] erneut an.
-
-
- Asset [ITEM] konnte nicht geladen werden.
-
Die Anzeige der aktuellen Position in der Menüleiste wurde als Standard für Starlight-Oberflächendesigns deaktiviert.
diff --git a/indra/newview/skins/default/xui/en/floater_fs_export.xml b/indra/newview/skins/default/xui/en/floater_fs_export.xml
index f66a061573..771410d24d 100644
--- a/indra/newview/skins/default/xui/en/floater_fs_export.xml
+++ b/indra/newview/skins/default/xui/en/floater_fs_export.xml
@@ -1,32 +1,161 @@
-
+
+ Backup [OBJECT] to Hard Disk...
+
+
+ Backup [OBJECT] working - Gathering information...
+
+
+ Backup [OBJECT] working - Fetching inventory...
+
+
+ Backup [OBJECT] working - Fetching assets...
+
+
+ Backup [OBJECT] working - Fetching textures...
+
+
-
+ width="500"
+ height="142"
+ left="0"
+ orientation="horizontal"
+ top="18"
+ show_drag_handle="true"
+ name="resizing_stack">
+
+
+ Selection Info
+
+
+ Exportable prims: [COUNT]/[TOTAL]
+
+
+ Exportable textures: [COUNT]/[TOTAL]
+
+
+ Options:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_fs_import.xml b/indra/newview/skins/default/xui/en/floater_fs_import.xml
index 78b186731c..dcbf0a5865 100644
--- a/indra/newview/skins/default/xui/en/floater_fs_import.xml
+++ b/indra/newview/skins/default/xui/en/floater_fs_import.xml
@@ -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">
+
+ Import [FILENAME]
+
[LINKSETS] linksets. [PRIMS] prims. [TEXTURES] textures.
@@ -50,54 +54,75 @@
name="upload_cost">
Total cost of uploads: $L [COST].
-
+
+ object
+
+
+ objects
+
+
+ [FILENAME]
+
+
+ Created on [DATE_STRING]
+
+
+ by [AUTHOR] [GRID]
+
+
+ Client: [CLIENT] v.[VERSION]
+
Select a file.
-
-
+ top_pad="1"/>
+ top_pad="1" >
@@ -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" >
+
+
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 569cafc3ab..97b1341d0a 100755
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -363,8 +363,8 @@
visibility_control="FSEnableObjectExports"
name="import linkset">
+ function="File.ImportLinkset"
+ parameter="" />
@@ -1743,8 +1743,8 @@
visibility_control="FSEnableObjectExports"
name="import linkset">
+ function="File.ImportLinkset"
+ parameter="" />
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index a17de4edf5..6bf4f30294 100755
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -11431,10 +11431,10 @@ Export finished and saved to [FILENAME].
Export
-Export failed.
+Export failed unexpectedly. Please see the log for details.
Export
Successfully saved [OBJECT] to [FILENAME].
+
+
+ Export
+ Successfully imported [COUNT] [OBJECT].
+
Total scripts in region jumped from [OLD_VALUE] to [NEW_VALUE] ([DIFFERENCE]).
Total scripts in region dropped from [OLD_VALUE] to [NEW_VALUE] ([DIFFERENCE]).
Toggling the preprocessor will not take full effect until you close and reopen this editor.
-
-
- Beginning export...
- Export finished.
- Exporting mesh is not currently supported. Aborting export.
- Nothing was exported. Backup not created.
- LLSelect node for [OBJECT] not found. Using default prim instead.
- [OBJECT] failed permissions check. Using default prim.
- [ITEM] failed permissions check. Skipping.
- Attempted to export null texture.
- Loading texture [ITEM]...
- Successfully saved texture [TEXTURE].
- Saving [ITEM]...
- Failed to get texture [TEXTURE].
- Received null texture [TEXTURE].
- [ITEM] is not currently supported by the exporter. Skipping.
- Could not retrieve [ITEM]. (Status [STATUS] [EXT_STATUS])
- Requesting asset [ITEM]...
- Rerequesting inventory for [ITEM].
- Rerequesting texture [ITEM].
- Failed to load asset [ITEM].
Showing your current location in the menu bar was disabled as a default for the Starlight skin series.
diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml
index a08eb82eb4..17b9172302 100755
--- a/indra/newview/skins/default/xui/pl/strings.xml
+++ b/indra/newview/skins/default/xui/pl/strings.xml
@@ -5278,63 +5278,6 @@ Spróbuj załączyć ścieżkę do edytora w cytowaniu.
Przełączenie trybu preprocesora odniesie pełny skutek dopiero po zamknięciu i ponownym otwarciu tego edytora.
-
- Rozpoczynanie eksportu...
-
-
- Eksportowanie zakończone.
-
-
- Eksportowanie meszy jest obecnie nieobsługiwane. Anulowano.
-
-
- Nic nie zostało wyeksportowane. Kopia nie została stworzona.
-
-
- Nie znaleziono węzła obiektu [OBJECT] metodą LLSelect. Używam primy domyślnej zamiast tego.
-
-
- [OBJECT] nie ma odpowiednich zezwoleń. Używam primy domyślnej.
-
-
- [ITEM] nie ma odpowiednich zezwoleń. Pomijam.
-
-
- Próbowano eksportować pustą teksturę.
-
-
- Ładowanie tekstury [ITEM]...
-
-
- Pomyślnie zapisano teksturę [TEXTURE].
-
-
- Zapisywanie [ITEM]...
-
-
- Nie powiodło się pobranie tekstury [TEXTURE].
-
-
- Otrzymano pustą teksturę: [TEXTURE].
-
-
- [ITEM] jest obecnie nieobsługiwany przez eksporter. Pomijam.
-
-
- Nie można pobrać [ITEM]. (Status [STATUS] [EXT_STATUS])
-
-
- Pobieranie danych [ITEM]...
-
-
- Pobieranie zawartości dla [ITEM].
-
-
- Pobieranie tekstury [ITEM].
-
-
- Nie powiodło się pobranie danych [ITEM].
-
Pokazywanie Twojej obecnej lokalizacji w pasku menu zostało wyłączone, to domyślne zachowanie dla skórek linii StarLight.