Removed Import/Export
This commit is contained in:
@@ -74,7 +74,6 @@ set(viewer_SOURCE_FILES
|
||||
ascentfloatercontactgroups.cpp
|
||||
ascentprefssys.cpp
|
||||
ascentprefsvan.cpp
|
||||
ascentuploadbrowser.cpp
|
||||
dhparam.cpp
|
||||
dsaparam.cpp
|
||||
emerald.cpp
|
||||
@@ -184,7 +183,6 @@ set(viewer_SOURCE_FILES
|
||||
llfloatereditui.cpp
|
||||
llfloaterenvsettings.cpp
|
||||
llfloaterevent.cpp
|
||||
llfloaterexport.cpp
|
||||
llfloaterexploreanimations.cpp
|
||||
llfloaterexploresounds.cpp
|
||||
llfloaterfriends.cpp
|
||||
@@ -201,7 +199,6 @@ set(viewer_SOURCE_FILES
|
||||
llfloaterhtmlsimple.cpp
|
||||
llfloaterhud.cpp
|
||||
llfloaterimagepreview.cpp
|
||||
llfloaterimport.cpp
|
||||
llfloaterinspect.cpp
|
||||
llfloaterjoystick.cpp
|
||||
llfloaterlagmeter.cpp
|
||||
@@ -269,7 +266,6 @@ set(viewer_SOURCE_FILES
|
||||
llhudtext.cpp
|
||||
llhudview.cpp
|
||||
llimpanel.cpp
|
||||
llimportobject.cpp
|
||||
llimview.cpp
|
||||
llinventoryactions.cpp
|
||||
llinventorybackup.cpp
|
||||
@@ -547,7 +543,6 @@ set(viewer_HEADER_FILES
|
||||
ascentfloatercontactgroups.h
|
||||
ascentprefssys.h
|
||||
ascentprefsvan.h
|
||||
ascentuploadbrowser.h
|
||||
emerald.h
|
||||
emeraldboobutils.h
|
||||
dofloaterhex.h
|
||||
@@ -656,7 +651,6 @@ set(viewer_HEADER_FILES
|
||||
llfloaterdirectory.h
|
||||
llfloatereditui.h
|
||||
llfloaterenvsettings.h
|
||||
llfloaterexport.h
|
||||
llfloaterexploreanimations.h
|
||||
llfloaterexploresounds.h
|
||||
llfloaterevent.h
|
||||
@@ -674,7 +668,6 @@ set(viewer_HEADER_FILES
|
||||
llfloaterhtmlsimple.h
|
||||
llfloaterhud.h
|
||||
llfloaterimagepreview.h
|
||||
llfloaterimport.h
|
||||
llfloaterinspect.h
|
||||
llfloaterjoystick.h
|
||||
llfloaterlagmeter.h
|
||||
@@ -741,7 +734,6 @@ set(viewer_HEADER_FILES
|
||||
llhudtext.h
|
||||
llhudview.h
|
||||
llimpanel.h
|
||||
llimportobject.h
|
||||
llimview.h
|
||||
llinventorybackup.h
|
||||
llinventorybridge.h
|
||||
|
||||
@@ -1,366 +0,0 @@
|
||||
/**
|
||||
* @file ascentuploadbrowser.h
|
||||
* @Author Duncan Garrett (Hg Beeks)
|
||||
* Meant as a replacement to using a system file browser for uploads.
|
||||
*
|
||||
* Created August 27 2010
|
||||
*
|
||||
* ALL SOURCE CODE IS PROVIDED "AS IS." THE CREATOR MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* k ilu bye
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
|
||||
#include "ascentuploadbrowser.h"
|
||||
|
||||
//UI Elements
|
||||
#include "llbutton.h" //Buttons
|
||||
#include "llcombobox.h" //Combo dropdowns
|
||||
#include "llscrolllistctrl.h" //List box for filenames
|
||||
#include "lluictrlfactory.h" //Loads the XUI
|
||||
|
||||
// project includes
|
||||
#include "llresmgr.h"
|
||||
#include "llsdserialize.h" //XML Parsing - Probably not needed
|
||||
#include "llviewercontrol.h"
|
||||
#include "llviewerwindow.h"
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Local function declarations, constants, enums, and typedefs
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
LLSD ASFloaterUploadBrowser::mUploaderSettings;
|
||||
ASFloaterUploadBrowser* ASFloaterUploadBrowser::sInstance = NULL;
|
||||
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class ASFloaterUploadBrowser
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
// Default constructor
|
||||
ASFloaterUploadBrowser::ASFloaterUploadBrowser()
|
||||
: LLFloater(std::string("floater_upload_browser"),
|
||||
std::string("FloaterUploadRect"),
|
||||
LLStringUtil::null)
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_upload_browser.xml");
|
||||
|
||||
mUploaderSettings.clear();
|
||||
mUploaderSettings = gSavedSettings.getLLSD("AscentUploadSettings");
|
||||
|
||||
mPathName = mUploaderSettings["ActivePath"].asString();
|
||||
if (mPathName == "None")
|
||||
mPathName = gDirUtilp->getExecutableDir();
|
||||
mFilterType = "None";
|
||||
|
||||
|
||||
//File list ------------------------------------------------------
|
||||
mFileList = getChild<LLScrollListCtrl>("file_list");
|
||||
childSetCommitCallback("file_list", onClickFile, this);
|
||||
childSetDoubleClickCallback("file_list", onDoubleClick);
|
||||
|
||||
//Above File List ------------------------------------------------
|
||||
|
||||
mBookmarkCombo = getChild<LLComboBox>("bookmark_combo");
|
||||
S32 index;
|
||||
for (index = 0; index < mUploaderSettings["Bookmarks"].size(); index++)
|
||||
{
|
||||
std::string bookmark = mUploaderSettings["Bookmarks"][index].asString();
|
||||
if (bookmark != "")
|
||||
mBookmarkCombo->add(bookmark, ADD_BOTTOM);
|
||||
}
|
||||
|
||||
mDriveCombo = getChild<LLComboBox>("drive_combo");
|
||||
childSetCommitCallback("drive_combo", onChangeDrives, this);
|
||||
//This is so unbelievably shitty I can't handle it -HgB
|
||||
std::string drive_letters[] = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"}; //Oh my god it's somehow worse now -HgB
|
||||
|
||||
mDriveCombo->removeall();
|
||||
for (index = 0; index < 26; index++)
|
||||
{
|
||||
std::string dir = drive_letters[index] + ":";
|
||||
S32 file_count = gDirUtilp->countFilesInDir(dir + gDirUtilp->getDirDelimiter(), "*.*");
|
||||
if(file_count)
|
||||
{
|
||||
mDriveCombo->add(dir, ADD_BOTTOM);
|
||||
}
|
||||
}
|
||||
|
||||
childSetAction("directory_button", onClickFilepathGoto, this);
|
||||
childSetCommitCallback("dir_path", onDirCommit, (void*)this);
|
||||
//Below File List ------------------------------------------------
|
||||
childSetCommitCallback("file_filter_combo", onUpdateFilter, this);
|
||||
|
||||
|
||||
refresh();
|
||||
mFileList->sortByColumn(std::string("file_name"), TRUE);
|
||||
mFileList->sortByColumn(std::string("file_type"), TRUE);
|
||||
childHide("multiple_uploads_label");
|
||||
childHide("bad_image_text");
|
||||
}
|
||||
|
||||
// Destroys the object
|
||||
ASFloaterUploadBrowser::~ASFloaterUploadBrowser()
|
||||
{
|
||||
sInstance = NULL;
|
||||
}
|
||||
|
||||
void ASFloaterUploadBrowser::onDirCommit(LLUICtrl* ctrl, void* data)
|
||||
{
|
||||
ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)data;
|
||||
if (panelp)
|
||||
{
|
||||
panelp->onClickFilepathGoto(data);
|
||||
}
|
||||
}
|
||||
|
||||
void ASFloaterUploadBrowser::updateBrowser(void* data, std::string new_path)
|
||||
{
|
||||
ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)data;
|
||||
if ((new_path != panelp->mPathName)||(new_path == ""))
|
||||
{
|
||||
panelp->mPathName = new_path;
|
||||
panelp->refresh();
|
||||
panelp->mFileList->selectFirstItem();
|
||||
panelp->childSetValue("asset_name", "");
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void ASFloaterUploadBrowser::onClickFilepathGoto(void* data)
|
||||
{
|
||||
ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)data;
|
||||
std::string new_path = panelp->childGetValue("dir_path");
|
||||
panelp->updateBrowser(data, new_path);
|
||||
}
|
||||
|
||||
void ASFloaterUploadBrowser::onClickFile(LLUICtrl* ctrl, void* user_data)
|
||||
{
|
||||
ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)user_data;
|
||||
panelp->refreshUploadOptions();
|
||||
}
|
||||
|
||||
void ASFloaterUploadBrowser::onChangeDrives(LLUICtrl* ctrl, void* user_data)
|
||||
{
|
||||
ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)user_data;
|
||||
if (panelp->mDriveCombo->getSelectedValue().asString() != panelp->mFilterType)
|
||||
{
|
||||
panelp->updateBrowser(user_data, panelp->mDriveCombo->getSelectedValue().asString());
|
||||
}
|
||||
}
|
||||
|
||||
void ASFloaterUploadBrowser::onUpdateFilter(LLUICtrl* ctrl, void* user_data)
|
||||
{
|
||||
ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)user_data;
|
||||
LLComboBox* combo = panelp->getChild<LLComboBox>("file_filter_combo");
|
||||
if (combo->getSelectedValue().asString() != panelp->mFilterType)
|
||||
{
|
||||
panelp->mFilterType = "";
|
||||
panelp->mFilterType = combo->getSelectedValue().asString();
|
||||
panelp->updateBrowser(user_data, "");
|
||||
}
|
||||
}
|
||||
|
||||
void ASFloaterUploadBrowser::refreshUploadOptions()
|
||||
{
|
||||
if (!mFileList->isEmpty())
|
||||
{
|
||||
if(!mFileList->getSelectedIDs().count())
|
||||
{
|
||||
llinfos << "No selection, clearing field." << llendl;
|
||||
childSetValue("asset_name", "");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mFileList->getFirstSelected()->getColumn(LIST_ASSET_TYPE)->getValue().asInteger() == LIST_TYPE_FILE)
|
||||
{
|
||||
std::string name;
|
||||
bool show_tex = false;
|
||||
bool show_snd = false;
|
||||
bool show_anm = false;
|
||||
bool show_multiple = false;
|
||||
if (mFileList->getAllSelected().size() > 1)
|
||||
{
|
||||
|
||||
llinfos << "Selected multiple files." << llendl;
|
||||
name = "(Multiple)";
|
||||
show_multiple = true;
|
||||
/*LLButton* expand_button = getChild<LLButton>("expand_collapse_btn");
|
||||
expand_button->setLabelArg("[COST]", std::string(mFileList->getAllSelected().size() * 10));*/
|
||||
childSetValue("multiple_uploads_label", "Multiple files selected. Total cost is: " + llformat("%d", mFileList->getAllSelected().size() * 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
int type = mFileList->getFirstSelected()->getColumn(LIST_FILE_TYPE)->getValue().asInteger();
|
||||
llinfos << "Selected a file, type" << type << llendl;
|
||||
if (type == FILE_TEXTURE)
|
||||
{
|
||||
show_tex = true;
|
||||
}
|
||||
else if (type == FILE_SOUND)
|
||||
{
|
||||
show_snd = true;
|
||||
}
|
||||
else if (type == FILE_ANIMATION)
|
||||
{
|
||||
show_anm = true;
|
||||
}
|
||||
name = mFileList->getFirstSelected()->getColumn(LIST_FILE_NAME)->getValue().asString();
|
||||
|
||||
}
|
||||
childSetVisible("texture_preview_label", (show_tex && !show_multiple));
|
||||
childSetVisible("texture_preview_combo", (show_tex && !show_multiple));
|
||||
childSetVisible("multiple_uploads_label", show_multiple);
|
||||
childSetValue("asset_name", name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ASFloaterUploadBrowser::onDoubleClick(void* user_data)
|
||||
{
|
||||
ASFloaterUploadBrowser* panelp = (ASFloaterUploadBrowser*)user_data;
|
||||
panelp->handleDoubleClick();
|
||||
}
|
||||
|
||||
void ASFloaterUploadBrowser::handleDoubleClick()
|
||||
{
|
||||
if (mFileList->getFirstSelected()->getColumn(LIST_ASSET_TYPE)->getValue().asInteger() == LIST_TYPE_PARENT)
|
||||
{
|
||||
S32 dirLimiterIndex = mPathName.find_last_of(gDirUtilp->getDirDelimiter());
|
||||
mPathName = mPathName.substr(0, dirLimiterIndex);
|
||||
refresh();
|
||||
mFileList->selectFirstItem();
|
||||
}
|
||||
else if (mFileList->getFirstSelected()->getColumn(LIST_ASSET_TYPE)->getValue().asInteger() == LIST_TYPE_FOLDER)
|
||||
{
|
||||
//Make sure that it's an actual folder so you don't get stuck - Specifically meant for files with no extension. -HgB
|
||||
std::string new_path = mPathName + gDirUtilp->getDirDelimiter() + mFileList->getFirstSelected()->getColumn(LIST_FILE_NAME)->getValue().asString();
|
||||
S32 file_count = gDirUtilp->countFilesInDir(new_path, "*.*");
|
||||
if(!file_count)
|
||||
return;
|
||||
mPathName = mPathName + gDirUtilp->getDirDelimiter() + mFileList->getFirstSelected()->getColumn(LIST_FILE_NAME)->getValue().asString();
|
||||
refresh();
|
||||
mFileList->selectFirstItem();
|
||||
|
||||
}
|
||||
childSetValue("asset_name", "");
|
||||
}
|
||||
|
||||
void ASFloaterUploadBrowser::refresh()
|
||||
{
|
||||
std::string filename;
|
||||
std::string fullPath = mPathName + gDirUtilp->getDirDelimiter();
|
||||
mFileList->deselectAllItems();
|
||||
mFileList->deleteAllItems();
|
||||
childSetValue("dir_path", gDirUtilp->getDirName(fullPath));
|
||||
mUploaderSettings["ActivePath"] = mPathName;
|
||||
gSavedSettings.setLLSD("AscentUploadSettings", mUploaderSettings);
|
||||
gDirUtilp->getNextFileInDir(gDirUtilp->getChatLogsDir(),"*", filename, false); //Clears the last file
|
||||
bool found = true;
|
||||
S32 file_count = 0;
|
||||
while(found)
|
||||
{
|
||||
found = gDirUtilp->getNextFileInDir(fullPath, "*.*", filename, false);
|
||||
if(found)
|
||||
{
|
||||
S32 periodIndex = filename.find_last_of(".");
|
||||
std::string extension = filename.substr(periodIndex + 1, filename.length() - 1);
|
||||
std::string extensionL = utf8str_tolower(extension);
|
||||
LLSD element;
|
||||
element["path"] = mPathName + filename;
|
||||
|
||||
LLSD& filename_column = element["columns"][LIST_FILE_NAME];
|
||||
filename_column["column"] = "file_name";
|
||||
filename_column["font"] = "SANSSERIF";
|
||||
filename_column["font-style"] = "NORMAL";
|
||||
|
||||
LLSD& filetype_column = element["columns"][LIST_FILE_TYPE];
|
||||
filetype_column["column"] = "file_type";
|
||||
filetype_column["type"] = "number";
|
||||
|
||||
LLSD& assettype_column = element["columns"][LIST_ASSET_TYPE];
|
||||
assettype_column["column"] = "asset_type";
|
||||
assettype_column["type"] = "number";
|
||||
|
||||
LLSD& invtype_column = element["columns"][LIST_INVENTORY_TYPE];
|
||||
invtype_column["column"] = "icon_inventory_type";
|
||||
invtype_column["type"] = "icon";
|
||||
invtype_column["value"] = "inv_folder_trash.tga";
|
||||
|
||||
|
||||
if (((extensionL == "jpeg")||(extensionL == "jpg")||(extensionL == "tga")
|
||||
||(extensionL == "png")||(extensionL == "bmp"))&&((mFilterType == "None")||(mFilterType == "Texture")))
|
||||
{
|
||||
invtype_column["value"] = "inv_item_texture.tga";
|
||||
filename_column["value"] = filename.substr(0, periodIndex);
|
||||
filetype_column["value"] = FILE_TEXTURE;
|
||||
assettype_column["value"] = LIST_TYPE_FILE;
|
||||
|
||||
}
|
||||
else if ((extensionL == "wav")&&((mFilterType == "None")||(mFilterType == "Sound")))
|
||||
{
|
||||
invtype_column["value"] = "inv_item_sound.tga";
|
||||
filename_column["value"] = filename.substr(0, periodIndex);
|
||||
filetype_column["value"] = FILE_SOUND;
|
||||
assettype_column["value"] = LIST_TYPE_FILE;
|
||||
}
|
||||
else if (((extensionL == "bvh")||(extensionL == "anim"))&&((mFilterType == "None")||(mFilterType == "Animation")))
|
||||
{
|
||||
invtype_column["value"] = "inv_item_animation.tga";
|
||||
filename_column["value"] = filename.substr(0, periodIndex);
|
||||
filetype_column["value"] = FILE_ANIMATION;
|
||||
assettype_column["value"] = LIST_TYPE_FILE;
|
||||
}
|
||||
else if ((extension == filename.substr(0, filename.length() - 1))&&(filename != "."))
|
||||
{
|
||||
std::string test_path = mPathName + gDirUtilp->getDirDelimiter() + filename + gDirUtilp->getDirDelimiter();
|
||||
S32 file_count = gDirUtilp->countFilesInDir(test_path, "*.*");
|
||||
if(file_count)
|
||||
{
|
||||
invtype_column["value"] = "inv_folder_plain_closed.tga";
|
||||
filename_column["value"] = filename;
|
||||
filetype_column["value"] = FOLDER;
|
||||
assettype_column["value"] = LIST_TYPE_FOLDER;
|
||||
}
|
||||
}
|
||||
else if (filename == "..")
|
||||
{
|
||||
invtype_column["value"] = "inv_folder_plain_open.tga";
|
||||
filename_column["value"] = filename;
|
||||
filetype_column["value"] = FOLDER;
|
||||
assettype_column["value"] = LIST_TYPE_PARENT;
|
||||
}
|
||||
if (invtype_column["value"].asString() != "inv_folder_trash.tga")
|
||||
{
|
||||
mFileList->addElement(element, ADD_BOTTOM);
|
||||
if (assettype_column["value"].asInteger() == LIST_TYPE_FILE)
|
||||
{
|
||||
file_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::string result;
|
||||
LLResMgr::getInstance()->getIntegerString(result, file_count);
|
||||
if (result == "")
|
||||
result = "0";
|
||||
childSetTextArg("result_label", "[COUNT]", result);
|
||||
|
||||
mFileList->sortItems();
|
||||
llinfos << "Total files loaded: " << result << "." << llendl;
|
||||
}
|
||||
|
||||
// static
|
||||
void ASFloaterUploadBrowser::show(void*)
|
||||
{
|
||||
if (!sInstance)
|
||||
{
|
||||
sInstance = new ASFloaterUploadBrowser();
|
||||
}
|
||||
|
||||
sInstance->open(); /*Flawfinder: ignore*/
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
/**
|
||||
* @file ascentuploadbrowser.h
|
||||
* @Author Duncan Garrett
|
||||
* Meant as a replacement to using Windows' file browser for uploads.
|
||||
*
|
||||
* Created August 27 2010
|
||||
*
|
||||
* ALL SOURCE CODE IS PROVIDED "AS IS." THE CREATOR MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* k ilu bye
|
||||
*/
|
||||
|
||||
#ifndef ASCENT_UPLOAD_BROWSER
|
||||
#define ASCENT_UPLOAD_BROWSER
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llcombobox.h"
|
||||
|
||||
class LLScrollListCtrl;
|
||||
|
||||
class ASFloaterUploadBrowser : public LLFloater
|
||||
{
|
||||
public:
|
||||
using LLFloater::handleDoubleClick;
|
||||
|
||||
ASFloaterUploadBrowser();
|
||||
virtual ~ASFloaterUploadBrowser();
|
||||
//File list
|
||||
static void onClickFile(LLUICtrl* ctrl, void* user_data);
|
||||
static void onUpdateFilter(LLUICtrl* ctrl, void* user_data);
|
||||
static void onDoubleClick(void* user_data);
|
||||
static void onDirCommit (LLUICtrl* ctrl, void* data);
|
||||
static void onChangeDrives(LLUICtrl* ctrl, void* user_data);
|
||||
static void onClickFilepathGoto(void* data);
|
||||
|
||||
void updateBrowser(void* data, std::string new_path);
|
||||
void refresh();
|
||||
void refreshUploadOptions();
|
||||
void handleDoubleClick();
|
||||
static void show(void*);
|
||||
|
||||
std::vector<LLSD> datas;
|
||||
|
||||
private:
|
||||
static LLSD mUploaderSettings;
|
||||
static ASFloaterUploadBrowser* sInstance;
|
||||
enum FILE_COLUMN_ORDER
|
||||
{
|
||||
LIST_FILE_TYPE,
|
||||
LIST_ASSET_TYPE,
|
||||
LIST_INVENTORY_TYPE,
|
||||
LIST_FILE_NAME,
|
||||
LIST_DATA
|
||||
};
|
||||
enum FILE_TYPE_ORDER
|
||||
{
|
||||
LIST_TYPE_PARENT,
|
||||
LIST_TYPE_FOLDER,
|
||||
LIST_TYPE_FILE
|
||||
};
|
||||
enum FILE_TYPE
|
||||
{
|
||||
FOLDER,
|
||||
FILE_TEXTURE,
|
||||
FILE_SOUND,
|
||||
FILE_ANIMATION
|
||||
};
|
||||
LLScrollListCtrl* mFileList;
|
||||
LLComboBox* mDriveCombo;
|
||||
LLComboBox* mBookmarkCombo;
|
||||
|
||||
std::string mPathName;
|
||||
std::string mFilterType;
|
||||
};
|
||||
|
||||
|
||||
#endif // ASCENT_UPLOAD_BROWSER
|
||||
@@ -1,906 +0,0 @@
|
||||
// <edit>
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llfloaterexport.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llsdutil_math.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llchat.h"
|
||||
#include "llfloaterchat.h"
|
||||
#include "llfilepicker.h"
|
||||
#include "llagent.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llvoavatardefines.h"
|
||||
#include "llimportobject.h"
|
||||
#include "llviewerobjectlist.h"
|
||||
#include "llviewerregion.h"
|
||||
#include "llwindow.h"
|
||||
#include "llviewerimagelist.h"
|
||||
#include "lltexturecache.h"
|
||||
#include "llimage.h"
|
||||
#include "llappviewer.h"
|
||||
#include "llimagej2c.h"
|
||||
|
||||
std::vector<LLFloaterExport*> LLFloaterExport::instances;
|
||||
|
||||
class CacheReadResponder : public LLTextureCache::ReadResponder
|
||||
{
|
||||
public:
|
||||
CacheReadResponder(const LLUUID& id, const std::string& filename)
|
||||
: mID(id)
|
||||
{
|
||||
mFormattedImage = new LLImageJ2C;
|
||||
setImage(mFormattedImage);
|
||||
mFilename = filename;
|
||||
}
|
||||
void setData(U8* data, S32 datasize, S32 imagesize, S32 imageformat, BOOL imagelocal)
|
||||
{
|
||||
if(imageformat==IMG_CODEC_TGA && mFormattedImage->getCodec()==IMG_CODEC_J2C)
|
||||
{
|
||||
llwarns<<"Bleh its a tga not saving"<<llendl;
|
||||
mFormattedImage=NULL;
|
||||
mImageSize=0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (mFormattedImage.notNull())
|
||||
{
|
||||
llassert_always(mFormattedImage->getCodec() == imageformat);
|
||||
mFormattedImage->appendData(data, datasize);
|
||||
}
|
||||
else
|
||||
{
|
||||
mFormattedImage = LLImageFormatted::createFromType(imageformat);
|
||||
mFormattedImage->setData(data,datasize);
|
||||
}
|
||||
mImageSize = imagesize;
|
||||
mImageLocal = imagelocal;
|
||||
}
|
||||
|
||||
virtual void completed(bool success)
|
||||
{
|
||||
if(success && (mFormattedImage.notNull()) && mImageSize>0)
|
||||
{
|
||||
|
||||
llinfos << "SUCCESS getting texture "<<mID<< llendl;
|
||||
|
||||
llinfos << "Saving to "<< mFilename<<llendl;
|
||||
|
||||
if(!mFormattedImage->save(mFilename))
|
||||
{
|
||||
llinfos << "FAIL saving texture "<<mID<< llendl;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!success)
|
||||
llwarns << "FAIL NOT SUCCESSFUL getting texture "<<mID<< llendl;
|
||||
if(mFormattedImage.isNull())
|
||||
llwarns << "FAIL image is NULL "<<mID<< llendl;
|
||||
}
|
||||
}
|
||||
private:
|
||||
LLPointer<LLImageFormatted> mFormattedImage;
|
||||
LLUUID mID;
|
||||
std::string mFilename;
|
||||
};
|
||||
|
||||
|
||||
LLExportable::LLExportable(LLViewerObject* object, std::string name, std::map<U32,std::string>& primNameMap)
|
||||
: mObject(object),
|
||||
mType(EXPORTABLE_OBJECT),
|
||||
mPrimNameMap(&primNameMap)
|
||||
{
|
||||
}
|
||||
|
||||
LLExportable::LLExportable(LLVOAvatar* avatar, EWearableType type, std::map<U32,std::string>& primNameMap)
|
||||
: mAvatar(avatar),
|
||||
mType(EXPORTABLE_WEARABLE),
|
||||
mWearableType(type),
|
||||
mPrimNameMap(&primNameMap)
|
||||
{
|
||||
}
|
||||
|
||||
LLSD LLExportable::asLLSD()
|
||||
{
|
||||
if(mType == EXPORTABLE_OBJECT)
|
||||
{
|
||||
std::list<LLViewerObject*> prims;
|
||||
|
||||
prims.push_back(mObject);
|
||||
|
||||
LLViewerObject::child_list_t child_list = mObject->getChildren();
|
||||
for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
|
||||
{
|
||||
LLViewerObject* child = *i;
|
||||
if(child->getPCode() < LL_PCODE_APP)
|
||||
{
|
||||
prims.push_back(child);
|
||||
}
|
||||
}
|
||||
|
||||
LLSD llsd;
|
||||
|
||||
std::list<LLViewerObject*>::iterator prim_iter = prims.begin();
|
||||
std::list<LLViewerObject*>::iterator prims_end = prims.end();
|
||||
for( ; prim_iter != prims_end; ++prim_iter)
|
||||
{
|
||||
LLViewerObject* object = (*prim_iter);
|
||||
|
||||
LLSD prim_llsd;
|
||||
|
||||
prim_llsd["type"] = "prim";
|
||||
|
||||
if (!object->isRoot())
|
||||
{
|
||||
if(!object->getSubParent()->isAvatar())
|
||||
{
|
||||
// Parent id
|
||||
prim_llsd["parent"] = llformat("%d", object->getSubParent()->getLocalID());
|
||||
}
|
||||
}
|
||||
if(object->getSubParent())
|
||||
{
|
||||
if(object->getSubParent()->isAvatar())
|
||||
{
|
||||
// attachment-specific
|
||||
U8 state = object->getState();
|
||||
S32 attachpt = ((S32)((((U8)state & AGENT_ATTACH_MASK) >> 4) | (((U8)state & ~AGENT_ATTACH_MASK) << 4)));
|
||||
prim_llsd["attach"] = attachpt;
|
||||
}
|
||||
}
|
||||
|
||||
// Transforms
|
||||
prim_llsd["position"] = object->getPosition().getValue();
|
||||
prim_llsd["scale"] = object->getScale().getValue();
|
||||
prim_llsd["rotation"] = ll_sd_from_quaternion(object->getRotation());
|
||||
|
||||
// Flags
|
||||
prim_llsd["shadows"] = object->flagCastShadows();
|
||||
prim_llsd["phantom"] = object->flagPhantom();
|
||||
prim_llsd["physical"] = (BOOL)(object->mFlags & FLAGS_USE_PHYSICS);
|
||||
|
||||
// Volume params
|
||||
LLVolumeParams params = object->getVolume()->getParams();
|
||||
prim_llsd["volume"] = params.asLLSD();
|
||||
|
||||
// Extra params
|
||||
if (object->isFlexible())
|
||||
{
|
||||
// Flexible
|
||||
LLFlexibleObjectData* flex = (LLFlexibleObjectData*)object->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE);
|
||||
prim_llsd["flexible"] = flex->asLLSD();
|
||||
}
|
||||
if (object->getParameterEntryInUse(LLNetworkData::PARAMS_LIGHT))
|
||||
{
|
||||
// Light
|
||||
LLLightParams* light = (LLLightParams*)object->getParameterEntry(LLNetworkData::PARAMS_LIGHT);
|
||||
prim_llsd["light"] = light->asLLSD();
|
||||
}
|
||||
if (object->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
|
||||
{
|
||||
// Sculpt
|
||||
LLSculptParams* sculpt = (LLSculptParams*)object->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
|
||||
prim_llsd["sculpt"] = sculpt->asLLSD();
|
||||
}
|
||||
|
||||
// Textures
|
||||
LLSD te_llsd;
|
||||
U8 te_count = object->getNumTEs();
|
||||
for (U8 i = 0; i < te_count; i++)
|
||||
{
|
||||
te_llsd.append(object->getTE(i)->asLLSD());
|
||||
}
|
||||
prim_llsd["textures"] = te_llsd;
|
||||
|
||||
std::map<U32,std::string>::iterator pos = (*mPrimNameMap).find(object->getLocalID());
|
||||
if(pos != (*mPrimNameMap).end())
|
||||
prim_llsd["name"] = (*mPrimNameMap)[object->getLocalID()];
|
||||
|
||||
llsd[llformat("%d", object->getLocalID())] = prim_llsd;
|
||||
}
|
||||
|
||||
return llsd;
|
||||
}
|
||||
else if(mType == EXPORTABLE_WEARABLE)
|
||||
{
|
||||
LLSD llsd; // pointless map with single key/value
|
||||
|
||||
LLSD item_sd; // map for wearable
|
||||
|
||||
item_sd["type"] = "wearable";
|
||||
|
||||
S32 type_s32 = (S32)mWearableType;
|
||||
std::string wearable_name = LLWearable::typeToTypeName( mWearableType );
|
||||
|
||||
item_sd["name"] = mAvatar->getFullname() + " " + wearable_name;
|
||||
item_sd["wearabletype"] = type_s32;
|
||||
|
||||
LLSD param_map;
|
||||
|
||||
for( LLVisualParam* param = mAvatar->getFirstVisualParam(); param; param = mAvatar->getNextVisualParam() )
|
||||
{
|
||||
LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
|
||||
if( (viewer_param->getWearableType() == type_s32) &&
|
||||
(viewer_param->isTweakable()) )
|
||||
{
|
||||
param_map[llformat("%d", viewer_param->getID())] = viewer_param->getWeight();
|
||||
}
|
||||
}
|
||||
|
||||
item_sd["params"] = param_map;
|
||||
|
||||
LLSD textures_map;
|
||||
|
||||
for( S32 te = 0; te < LLVOAvatarDefines::TEX_NUM_INDICES; te++ )
|
||||
{
|
||||
if( LLVOAvatar::getTEWearableType( (LLVOAvatarDefines::ETextureIndex)te ) == mWearableType )
|
||||
{
|
||||
LLViewerImage* te_image = mAvatar->getTEImage( te );
|
||||
if( te_image )
|
||||
{
|
||||
textures_map[llformat("%d", te)] = te_image->getID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
item_sd["textures"] = textures_map;
|
||||
|
||||
// Generate a unique ID for it...
|
||||
LLUUID myid;
|
||||
myid.generate();
|
||||
|
||||
llsd[myid.asString()] = item_sd;
|
||||
|
||||
return llsd;
|
||||
}
|
||||
return LLSD();
|
||||
}
|
||||
|
||||
|
||||
|
||||
LLFloaterExport::LLFloaterExport()
|
||||
: LLFloater()
|
||||
{
|
||||
mSelection = LLSelectMgr::getInstance()->getSelection();
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_export.xml");
|
||||
LLFloaterExport::instances.push_back(this);
|
||||
}
|
||||
|
||||
|
||||
LLFloaterExport::~LLFloaterExport()
|
||||
{
|
||||
std::vector<LLFloaterExport*>::iterator pos = std::find(LLFloaterExport::instances.begin(), LLFloaterExport::instances.end(), this);
|
||||
if(pos != LLFloaterExport::instances.end())
|
||||
{
|
||||
LLFloaterExport::instances.erase(pos);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLFloaterExport::postBuild(void)
|
||||
{
|
||||
if(!mSelection) return TRUE;
|
||||
if(mSelection->getRootObjectCount() < 1) return TRUE;
|
||||
|
||||
// New stuff: Populate prim name map
|
||||
|
||||
for (LLObjectSelection::valid_iterator iter = mSelection->valid_begin();
|
||||
iter != mSelection->valid_end(); iter++)
|
||||
{
|
||||
LLSelectNode* nodep = *iter;
|
||||
LLViewerObject* objectp = nodep->getObject();
|
||||
U32 localid = objectp->getLocalID();
|
||||
std::string name = nodep->mName;
|
||||
mPrimNameMap[localid] = name;
|
||||
}
|
||||
|
||||
// Older stuff
|
||||
|
||||
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("export_list");
|
||||
|
||||
std::map<LLViewerObject*, bool> avatars;
|
||||
|
||||
for (LLObjectSelection::valid_root_iterator iter = mSelection->valid_root_begin();
|
||||
iter != mSelection->valid_root_end(); iter++)
|
||||
{
|
||||
LLSelectNode* nodep = *iter;
|
||||
LLViewerObject* objectp = nodep->getObject();
|
||||
std::string objectp_id = llformat("%d", objectp->getLocalID());
|
||||
|
||||
if(list->getItemIndex(objectp->getID()) == -1)
|
||||
{
|
||||
bool is_attachment = false;
|
||||
bool is_root = true;
|
||||
LLViewerObject* parentp = objectp->getSubParent();
|
||||
if(parentp)
|
||||
{
|
||||
if(!parentp->isAvatar())
|
||||
{
|
||||
// parent is a prim I guess
|
||||
is_root = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
// parent is an avatar
|
||||
is_attachment = true;
|
||||
if(!avatars[parentp]) avatars[parentp] = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool is_prim = true;
|
||||
if(objectp->getPCode() >= LL_PCODE_APP)
|
||||
{
|
||||
is_prim = false;
|
||||
}
|
||||
|
||||
bool is_avatar = objectp->isAvatar();
|
||||
|
||||
|
||||
if(is_root && is_prim)
|
||||
{
|
||||
LLSD element;
|
||||
element["id"] = objectp->getID();
|
||||
|
||||
LLSD& check_column = element["columns"][LIST_CHECKED];
|
||||
check_column["column"] = "checked";
|
||||
check_column["type"] = "checkbox";
|
||||
check_column["value"] = true;
|
||||
|
||||
LLSD& type_column = element["columns"][LIST_TYPE];
|
||||
type_column["column"] = "type";
|
||||
type_column["type"] = "icon";
|
||||
type_column["value"] = "inv_item_object.tga";
|
||||
|
||||
LLSD& name_column = element["columns"][LIST_NAME];
|
||||
name_column["column"] = "name";
|
||||
if(is_attachment)
|
||||
name_column["value"] = nodep->mName + " (worn on " + utf8str_tolower(objectp->getAttachmentPointName()) + ")";
|
||||
else
|
||||
name_column["value"] = nodep->mName;
|
||||
|
||||
LLSD& avatarid_column = element["columns"][LIST_AVATARID];
|
||||
avatarid_column["column"] = "avatarid";
|
||||
if(is_attachment)
|
||||
avatarid_column["value"] = parentp->getID();
|
||||
else
|
||||
avatarid_column["value"] = LLUUID::null;
|
||||
|
||||
LLExportable* exportable = new LLExportable(objectp, nodep->mName, mPrimNameMap);
|
||||
mExportables[objectp->getID()] = exportable->asLLSD();
|
||||
|
||||
list->addElement(element, ADD_BOTTOM);
|
||||
|
||||
addToPrimList(objectp);
|
||||
}
|
||||
else if(is_avatar)
|
||||
{
|
||||
if(!avatars[objectp])
|
||||
{
|
||||
avatars[objectp] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::map<LLViewerObject*, bool>::iterator avatar_iter = avatars.begin();
|
||||
std::map<LLViewerObject*, bool>::iterator avatars_end = avatars.end();
|
||||
for( ; avatar_iter != avatars_end; avatar_iter++)
|
||||
{
|
||||
LLViewerObject* avatar = (*avatar_iter).first;
|
||||
addAvatarStuff((LLVOAvatar*)avatar);
|
||||
}
|
||||
|
||||
updateNamesProgress();
|
||||
|
||||
childSetAction("select_all_btn", onClickSelectAll, this);
|
||||
childSetAction("select_objects_btn", onClickSelectObjects, this);
|
||||
childSetAction("select_wearables_btn", onClickSelectWearables, this);
|
||||
|
||||
childSetAction("save_as_btn", onClickSaveAs, this);
|
||||
childSetAction("make_copy_btn", onClickMakeCopy, this);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterExport::addAvatarStuff(LLVOAvatar* avatarp)
|
||||
{
|
||||
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("export_list");
|
||||
for( S32 type = WT_SHAPE; type < WT_COUNT; type++ )
|
||||
{
|
||||
// guess whether this wearable actually exists
|
||||
// by checking whether it has any textures that aren't default
|
||||
bool exists = false;
|
||||
if(type == WT_SHAPE)
|
||||
{
|
||||
exists = true;
|
||||
}
|
||||
else if (type == WT_ALPHA || type == WT_TATTOO) //alpha layers and tattos are unsupported for now
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( S32 te = 0; te < LLVOAvatarDefines::TEX_NUM_INDICES; te++ )
|
||||
{
|
||||
if( (S32)LLVOAvatar::getTEWearableType( (LLVOAvatarDefines::ETextureIndex)te ) == type )
|
||||
{
|
||||
LLViewerImage* te_image = avatarp->getTEImage( te );
|
||||
if( te_image->getID() != IMG_DEFAULT_AVATAR)
|
||||
{
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(exists)
|
||||
{
|
||||
std::string wearable_name = LLWearable::typeToTypeName( (EWearableType)type );
|
||||
std::string name = avatarp->getFullname() + " " + wearable_name;
|
||||
LLUUID myid;
|
||||
myid.generate();
|
||||
|
||||
LLSD element;
|
||||
element["id"] = myid;
|
||||
|
||||
LLSD& check_column = element["columns"][LIST_CHECKED];
|
||||
check_column["column"] = "checked";
|
||||
check_column["type"] = "checkbox";
|
||||
check_column["value"] = false;
|
||||
|
||||
LLSD& type_column = element["columns"][LIST_TYPE];
|
||||
type_column["column"] = "type";
|
||||
type_column["type"] = "icon";
|
||||
type_column["value"] = "inv_item_" + wearable_name + ".tga";
|
||||
|
||||
LLSD& name_column = element["columns"][LIST_NAME];
|
||||
name_column["column"] = "name";
|
||||
name_column["value"] = name;
|
||||
|
||||
LLSD& avatarid_column = element["columns"][LIST_AVATARID];
|
||||
avatarid_column["column"] = "avatarid";
|
||||
avatarid_column["value"] = avatarp->getID();
|
||||
|
||||
LLExportable* exportable = new LLExportable(avatarp, (EWearableType)type, mPrimNameMap);
|
||||
mExportables[myid] = exportable->asLLSD();
|
||||
|
||||
list->addElement(element, ADD_BOTTOM);
|
||||
}
|
||||
}
|
||||
|
||||
// Add attachments
|
||||
LLViewerObject::child_list_t child_list = avatarp->getChildren();
|
||||
for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
|
||||
{
|
||||
LLViewerObject* childp = *i;
|
||||
if(list->getItemIndex(childp->getID()) == -1)
|
||||
{
|
||||
LLSD element;
|
||||
element["id"] = childp->getID();
|
||||
|
||||
LLSD& check_column = element["columns"][LIST_CHECKED];
|
||||
check_column["column"] = "checked";
|
||||
check_column["type"] = "checkbox";
|
||||
check_column["value"] = false;
|
||||
|
||||
LLSD& type_column = element["columns"][LIST_TYPE];
|
||||
type_column["column"] = "type";
|
||||
type_column["type"] = "icon";
|
||||
type_column["value"] = "inv_item_object.tga";
|
||||
|
||||
LLSD& name_column = element["columns"][LIST_NAME];
|
||||
name_column["column"] = "name";
|
||||
name_column["value"] = "Object (worn on " + utf8str_tolower(childp->getAttachmentPointName()) + ")";
|
||||
|
||||
LLSD& avatarid_column = element["columns"][LIST_AVATARID];
|
||||
avatarid_column["column"] = "avatarid";
|
||||
avatarid_column["value"] = avatarp->getID();
|
||||
|
||||
LLExportable* exportable = new LLExportable(childp, "Object", mPrimNameMap);
|
||||
mExportables[childp->getID()] = exportable->asLLSD();
|
||||
|
||||
list->addElement(element, ADD_BOTTOM);
|
||||
|
||||
addToPrimList(childp);
|
||||
//LLSelectMgr::getInstance()->selectObjectAndFamily(childp, false);
|
||||
//LLSelectMgr::getInstance()->deselectObjectAndFamily(childp, true, true);
|
||||
|
||||
LLViewerObject::child_list_t select_list = childp->getChildren();
|
||||
LLViewerObject::child_list_t::iterator select_iter;
|
||||
int block_counter;
|
||||
|
||||
gMessageSystem->newMessageFast(_PREHASH_ObjectSelect);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
|
||||
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, childp->getLocalID());
|
||||
block_counter = 0;
|
||||
for (select_iter = select_list.begin(); select_iter != select_list.end(); ++select_iter)
|
||||
{
|
||||
block_counter++;
|
||||
if(block_counter >= 254)
|
||||
{
|
||||
// start a new message
|
||||
gMessageSystem->sendReliable(childp->getRegion()->getHost());
|
||||
gMessageSystem->newMessageFast(_PREHASH_ObjectSelect);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
}
|
||||
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
|
||||
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*select_iter)->getLocalID());
|
||||
}
|
||||
gMessageSystem->sendReliable(childp->getRegion()->getHost());
|
||||
|
||||
gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
|
||||
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, childp->getLocalID());
|
||||
block_counter = 0;
|
||||
for (select_iter = select_list.begin(); select_iter != select_list.end(); ++select_iter)
|
||||
{
|
||||
block_counter++;
|
||||
if(block_counter >= 254)
|
||||
{
|
||||
// start a new message
|
||||
gMessageSystem->sendReliable(childp->getRegion()->getHost());
|
||||
gMessageSystem->newMessageFast(_PREHASH_ObjectDeselect);
|
||||
gMessageSystem->nextBlockFast(_PREHASH_AgentData);
|
||||
gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
|
||||
gMessageSystem->addUUID(_PREHASH_SessionID, gAgent.getSessionID());
|
||||
}
|
||||
gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
|
||||
gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, (*select_iter)->getLocalID());
|
||||
}
|
||||
gMessageSystem->sendReliable(childp->getRegion()->getHost());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFloaterExport::onClickSelectAll(void* user_data)
|
||||
{
|
||||
LLFloaterExport* floater = (LLFloaterExport*)user_data;
|
||||
LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("export_list");
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
|
||||
std::vector<LLScrollListItem*>::iterator items_end = items.end();
|
||||
bool new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue());
|
||||
for( ; item_iter != items_end; ++item_iter)
|
||||
{
|
||||
LLScrollListItem* item = (*item_iter);
|
||||
item->getColumn(LIST_CHECKED)->setValue(new_value);
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFloaterExport::onClickSelectObjects(void* user_data)
|
||||
{
|
||||
LLFloaterExport* floater = (LLFloaterExport*)user_data;
|
||||
LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("export_list");
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
|
||||
std::vector<LLScrollListItem*>::iterator items_end = items.end();
|
||||
bool new_value = false;
|
||||
for( ; item_iter != items_end; ++item_iter)
|
||||
{
|
||||
if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() == "inv_item_object.tga")
|
||||
{
|
||||
new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(item_iter = items.begin(); item_iter != items_end; ++item_iter)
|
||||
{
|
||||
if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() == "inv_item_object.tga")
|
||||
{
|
||||
LLScrollListItem* item = (*item_iter);
|
||||
item->getColumn(LIST_CHECKED)->setValue(new_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFloaterExport::onClickSelectWearables(void* user_data)
|
||||
{
|
||||
LLFloaterExport* floater = (LLFloaterExport*)user_data;
|
||||
LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("export_list");
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
|
||||
std::vector<LLScrollListItem*>::iterator items_end = items.end();
|
||||
bool new_value = false;
|
||||
for( ; item_iter != items_end; ++item_iter)
|
||||
{
|
||||
if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() != "inv_item_object.tga")
|
||||
{
|
||||
new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(item_iter = items.begin(); item_iter != items_end; ++item_iter)
|
||||
{
|
||||
if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() != "inv_item_object.tga")
|
||||
{
|
||||
LLScrollListItem* item = (*item_iter);
|
||||
item->getColumn(LIST_CHECKED)->setValue(new_value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLSD LLFloaterExport::getLLSD()
|
||||
{
|
||||
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("export_list");
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
LLSD sd;
|
||||
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
|
||||
std::vector<LLScrollListItem*>::iterator items_end = items.end();
|
||||
for( ; item_iter != items_end; ++item_iter)
|
||||
{
|
||||
LLScrollListItem* item = (*item_iter);
|
||||
if(item->getColumn(LIST_CHECKED)->getValue())
|
||||
{
|
||||
LLSD item_sd = mExportables[item->getUUID()];
|
||||
LLSD::map_iterator map_iter = item_sd.beginMap();
|
||||
LLSD::map_iterator map_end = item_sd.endMap();
|
||||
for( ; map_iter != map_end; ++map_iter)
|
||||
{
|
||||
std::string key((*map_iter).first);
|
||||
LLSD data = (*map_iter).second;
|
||||
// copy it...
|
||||
sd[key] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
return sd;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFloaterExport::onClickSaveAs(void* user_data)
|
||||
{
|
||||
LLFloaterExport* floater = (LLFloaterExport*)user_data;
|
||||
LLSD sd = floater->getLLSD();
|
||||
|
||||
if(sd.size())
|
||||
{
|
||||
std::string default_filename = "untitled";
|
||||
|
||||
// count the number of selected items
|
||||
LLScrollListCtrl* list = floater->getChild<LLScrollListCtrl>("export_list");
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
int item_count = 0;
|
||||
LLUUID avatarid = (*(items.begin()))->getColumn(LIST_AVATARID)->getValue().asUUID();
|
||||
bool all_same_avatarid = true;
|
||||
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
|
||||
std::vector<LLScrollListItem*>::iterator items_end = items.end();
|
||||
for( ; item_iter != items_end; ++item_iter)
|
||||
{
|
||||
LLScrollListItem* item = (*item_iter);
|
||||
if(item->getColumn(LIST_CHECKED)->getValue())
|
||||
{
|
||||
item_count++;
|
||||
if(item->getColumn(LIST_AVATARID)->getValue().asUUID() != avatarid)
|
||||
{
|
||||
all_same_avatarid = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(item_count == 1)
|
||||
{
|
||||
// Exporting one item? Use its name for the filename.
|
||||
// But make sure it's a root!
|
||||
LLSD target = (*(sd.beginMap())).second;
|
||||
if(target.has("parent"))
|
||||
{
|
||||
std::string parentid = target["parent"].asString();
|
||||
target = sd[parentid];
|
||||
}
|
||||
if(target.has("name"))
|
||||
{
|
||||
if(target["name"].asString().length() > 0)
|
||||
{
|
||||
default_filename = target["name"].asString();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Multiple items?
|
||||
// If they're all part of the same avatar, use the avatar's name as filename.
|
||||
if(all_same_avatarid)
|
||||
{
|
||||
std::string fullname;
|
||||
if(gCacheName->getFullName(avatarid, fullname))
|
||||
{
|
||||
default_filename = fullname;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLFilePicker& file_picker = LLFilePicker::instance();
|
||||
if(file_picker.getSaveFile( LLFilePicker::FFSAVE_XML, LLDir::getScrubbedFileName(default_filename + ".xml")))
|
||||
{
|
||||
std::string file_name = file_picker.getFirstFile();
|
||||
std::string path = file_name.substr(0,file_name.find_last_of(".")) + "_assets";
|
||||
BOOL download_texture = floater->childGetValue("download_textures");
|
||||
if(download_texture)
|
||||
{
|
||||
if(!LLFile::isdir(path))
|
||||
{
|
||||
LLFile::mkdir(path);
|
||||
}else
|
||||
{
|
||||
U32 response = OSMessageBox("Directory "+path+" already exists, would you like to continue and override files?", "Directory Already Exists", OSMB_YESNO);
|
||||
if(response)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
path.append(gDirUtilp->getDirDelimiter()); //lets add the Delimiter now
|
||||
}
|
||||
// set correct names within llsd and download textures
|
||||
LLSD::map_iterator map_iter = sd.beginMap();
|
||||
LLSD::map_iterator map_end = sd.endMap();
|
||||
std::list<LLUUID> textures;
|
||||
|
||||
for( ; map_iter != map_end; ++map_iter)
|
||||
{
|
||||
std::istringstream keystr((*map_iter).first);
|
||||
U32 key;
|
||||
keystr >> key;
|
||||
LLSD item = (*map_iter).second;
|
||||
if(item["type"].asString() == "prim")
|
||||
{
|
||||
std::string name = floater->mPrimNameMap[key];
|
||||
item["name"] = name;
|
||||
// I don't understand C++ :(
|
||||
sd[(*map_iter).first] = item;
|
||||
|
||||
if(download_texture)
|
||||
{
|
||||
//textures
|
||||
LLSD::array_iterator tex_iter = item["textures"].beginArray();
|
||||
for( ; tex_iter != item["textures"].endArray(); ++tex_iter)
|
||||
{
|
||||
textures.push_back((*tex_iter)["imageid"].asUUID());
|
||||
}
|
||||
if(item.has("sculpt"))
|
||||
{
|
||||
textures.push_back(item["sculpt"]["texture"].asUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(download_texture && item["type"].asString() == "wearable")
|
||||
{
|
||||
LLSD::map_iterator tex_iter = item["textures"].beginMap();
|
||||
for( ; tex_iter != item["textures"].endMap(); ++tex_iter)
|
||||
{
|
||||
textures.push_back((*tex_iter).second.asUUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
if(download_texture)
|
||||
{
|
||||
textures.unique();
|
||||
while(!textures.empty())
|
||||
{
|
||||
llinfos << "Requesting texture " << textures.front().asString() << llendl;
|
||||
LLViewerImage* img = gImageList.getImage(textures.front(), MIPMAP_TRUE, FALSE);
|
||||
img->setBoostLevel(LLViewerImageBoostLevel::BOOST_MAX_LEVEL);
|
||||
|
||||
CacheReadResponder* responder = new CacheReadResponder(textures.front(), std::string(path + textures.front().asString() + ".j2c"));
|
||||
LLAppViewer::getTextureCache()->readFromCache(textures.front(),LLWorkerThread::PRIORITY_HIGH,0,999999,responder);
|
||||
textures.pop_front();
|
||||
}
|
||||
}
|
||||
|
||||
llofstream export_file(file_name);
|
||||
LLSDSerialize::toPrettyXML(sd, export_file);
|
||||
export_file.close();
|
||||
|
||||
std::string msg = "Saved ";
|
||||
msg.append(file_name);
|
||||
if(download_texture) msg.append(" (Content might take some time to download)");
|
||||
LLChat chat(msg);
|
||||
LLFloaterChat::addChat(chat);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string msg = "No exportable items selected";
|
||||
LLChat chat(msg);
|
||||
LLFloaterChat::addChat(chat);
|
||||
return;
|
||||
}
|
||||
|
||||
floater->close();
|
||||
}
|
||||
|
||||
//static
|
||||
void LLFloaterExport::onClickMakeCopy(void* user_data)
|
||||
{
|
||||
LLFloaterExport* floater = (LLFloaterExport*)user_data;
|
||||
LLSD sd = floater->getLLSD();
|
||||
|
||||
if(sd.size())
|
||||
{
|
||||
LLXmlImport::import(new LLXmlImportOptions(sd));
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string msg = "No copyable items selected";
|
||||
LLChat chat(msg);
|
||||
LLFloaterChat::addChat(chat);
|
||||
return;
|
||||
}
|
||||
|
||||
// I guess close the floater because only one import is allowed at once anyway
|
||||
floater->close();
|
||||
}
|
||||
|
||||
void LLFloaterExport::addToPrimList(LLViewerObject* object)
|
||||
{
|
||||
mPrimList.push_back(object->getLocalID());
|
||||
LLViewerObject::child_list_t child_list = object->getChildren();
|
||||
for (LLViewerObject::child_list_t::iterator i = child_list.begin(); i != child_list.end(); ++i)
|
||||
{
|
||||
LLViewerObject* child = *i;
|
||||
if(child->getPCode() < LL_PCODE_APP)
|
||||
{
|
||||
mPrimList.push_back(child->getLocalID());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterExport::updateNamesProgress()
|
||||
{
|
||||
childSetText("names_progress_text", llformat("Names retrieved: %d of %d", mPrimNameMap.size(), mPrimList.size()));
|
||||
}
|
||||
|
||||
void LLFloaterExport::receivePrimName(LLViewerObject* object, std::string name)
|
||||
{
|
||||
LLUUID fullid = object->getID();
|
||||
U32 localid = object->getLocalID();
|
||||
if(std::find(mPrimList.begin(), mPrimList.end(), localid) != mPrimList.end())
|
||||
{
|
||||
mPrimNameMap[localid] = name;
|
||||
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("export_list");
|
||||
S32 item_index = list->getItemIndex(fullid);
|
||||
if(item_index != -1)
|
||||
{
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator iter = items.begin();
|
||||
std::vector<LLScrollListItem*>::iterator end = items.end();
|
||||
for( ; iter != end; ++iter)
|
||||
{
|
||||
if((*iter)->getUUID() == fullid)
|
||||
{
|
||||
(*iter)->getColumn(LIST_NAME)->setValue(name + " (worn on " + utf8str_tolower(object->getAttachmentPointName()) + ")");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
updateNamesProgress();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterExport::receiveObjectProperties(LLUUID fullid, std::string name, std::string desc)
|
||||
{
|
||||
LLViewerObject* object = gObjectList.findObject(fullid);
|
||||
std::vector<LLFloaterExport*>::iterator iter = LLFloaterExport::instances.begin();
|
||||
std::vector<LLFloaterExport*>::iterator end = LLFloaterExport::instances.end();
|
||||
for( ; iter != end; ++iter)
|
||||
{
|
||||
(*iter)->receivePrimName(object, name);
|
||||
}
|
||||
}
|
||||
|
||||
// </edit>
|
||||
@@ -1,114 +0,0 @@
|
||||
// <edit>
|
||||
#ifndef LL_LLFLOATEREXPORT_H
|
||||
#define LL_LLFLOATEREXPORT_H
|
||||
|
||||
#include "llfloater.h"
|
||||
#include "llselectmgr.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llvoavatardefines.h"
|
||||
|
||||
//class LLExportObject
|
||||
//{
|
||||
//public:
|
||||
// LLExportObject(LLViewerObject* object);
|
||||
// //LLExportObject(LLViewerObject* object, std::string name);
|
||||
//
|
||||
// LLSD asLLSD();
|
||||
//
|
||||
// LLViewerObject* mObject;
|
||||
//};
|
||||
//
|
||||
//class LLExportWearable
|
||||
//{
|
||||
//public:
|
||||
// LLExportWearable(LLVOAvatar* avatar, EWearableType type);
|
||||
//
|
||||
// LLSD asLLSD();
|
||||
// std::string getIcon();
|
||||
//
|
||||
// LLVOAvatar* mAvatar;
|
||||
// EWearableType mType;
|
||||
// std::string mName;
|
||||
//};
|
||||
//
|
||||
//
|
||||
//class LLExportBakedWearable // not used
|
||||
//{
|
||||
//public:
|
||||
// LLExportBakedWearable(LLVOAvatar* avatar, EWearableType type);
|
||||
//
|
||||
// LLSD asLLSD();
|
||||
// std::string getIcon();
|
||||
//
|
||||
// LLVOAvatar* mAvatar;
|
||||
// EWearableType mType;
|
||||
// std::string mName;
|
||||
//};
|
||||
|
||||
|
||||
|
||||
class LLExportable
|
||||
{
|
||||
enum EXPORTABLE_TYPE
|
||||
{
|
||||
EXPORTABLE_OBJECT,
|
||||
EXPORTABLE_WEARABLE
|
||||
};
|
||||
|
||||
public:
|
||||
LLExportable(LLViewerObject* object, std::string name, std::map<U32,std::string>& primNameMap);
|
||||
LLExportable(LLVOAvatar* avatar, EWearableType type, std::map<U32,std::string>& primNameMap);
|
||||
|
||||
LLSD asLLSD();
|
||||
|
||||
EXPORTABLE_TYPE mType;
|
||||
EWearableType mWearableType;
|
||||
LLViewerObject* mObject;
|
||||
LLVOAvatar* mAvatar;
|
||||
std::map<U32,std::string>* mPrimNameMap;
|
||||
};
|
||||
|
||||
|
||||
class LLFloaterExport
|
||||
: public LLFloater
|
||||
{
|
||||
public:
|
||||
LLFloaterExport();
|
||||
BOOL postBuild(void);
|
||||
void addAvatarStuff(LLVOAvatar* avatarp);
|
||||
void updateNamesProgress();
|
||||
void receivePrimName(LLViewerObject* object, std::string name);
|
||||
|
||||
LLSD getLLSD();
|
||||
|
||||
std::vector<U32> mPrimList;
|
||||
std::map<U32, std::string> mPrimNameMap;
|
||||
|
||||
static std::vector<LLFloaterExport*> instances; // for callback-type use
|
||||
|
||||
static void receiveObjectProperties(LLUUID fullid, std::string name, std::string desc);
|
||||
|
||||
static void onClickSelectAll(void* user_data);
|
||||
static void onClickSelectObjects(void* user_data);
|
||||
static void onClickSelectWearables(void* user_data);
|
||||
static void onClickSaveAs(void* user_data);
|
||||
static void onClickMakeCopy(void* user_data);
|
||||
|
||||
private:
|
||||
virtual ~LLFloaterExport();
|
||||
void addToPrimList(LLViewerObject* object);
|
||||
|
||||
enum LIST_COLUMN_ORDER
|
||||
{
|
||||
LIST_CHECKED,
|
||||
LIST_TYPE,
|
||||
LIST_NAME,
|
||||
LIST_AVATARID
|
||||
};
|
||||
|
||||
LLObjectSelectionHandle mSelection;
|
||||
std::map<LLUUID, LLSD> mExportables;
|
||||
};
|
||||
|
||||
#endif
|
||||
// </edit>
|
||||
@@ -1,363 +0,0 @@
|
||||
// <edit>
|
||||
/**
|
||||
* @file llfloaterimport.cpp
|
||||
*/
|
||||
|
||||
#include "llviewerprecompiledheaders.h"
|
||||
#include "llimportobject.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llviewerobject.h"
|
||||
#include "llagent.h"
|
||||
#include "llchat.h"
|
||||
#include "llfloaterchat.h"
|
||||
#include "llfloater.h"
|
||||
#include "lllineeditor.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llscrolllistctrl.h"
|
||||
#include "llfloaterimport.h"
|
||||
#include "llimportobject.h"
|
||||
|
||||
LLFloaterImportProgress* LLFloaterImportProgress::sInstance;
|
||||
|
||||
LLFloaterXmlImportOptions::LLFloaterXmlImportOptions(LLXmlImportOptions* default_options)
|
||||
: mDefaultOptions(default_options)
|
||||
{
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_import_options.xml");
|
||||
}
|
||||
|
||||
BOOL LLFloaterXmlImportOptions::postBuild()
|
||||
{
|
||||
center();
|
||||
LLScrollListCtrl* list = getChild<LLScrollListCtrl>("import_list");
|
||||
// Add all wearables to list and keep an id:ptr map
|
||||
std::vector<LLImportWearable*>::iterator wearable_end = mDefaultOptions->mWearables.end();
|
||||
for(std::vector<LLImportWearable*>::iterator iter = mDefaultOptions->mWearables.begin();
|
||||
iter != wearable_end; ++iter)
|
||||
{
|
||||
LLImportWearable* wearablep = (*iter);
|
||||
LLUUID id; id.generate();
|
||||
mImportWearableMap[id] = wearablep;
|
||||
LLSD element;
|
||||
element["id"] = id;
|
||||
LLSD& check_column = element["columns"][LIST_CHECKED];
|
||||
check_column["column"] = "checked";
|
||||
check_column["type"] = "checkbox";
|
||||
check_column["value"] = true;
|
||||
LLSD& type_column = element["columns"][LIST_TYPE];
|
||||
type_column["column"] = "type";
|
||||
type_column["type"] = "icon";
|
||||
type_column["value"] = "inv_item_" + LLWearable::typeToTypeName((EWearableType)(wearablep->mType)) + ".tga";
|
||||
LLSD& name_column = element["columns"][LIST_NAME];
|
||||
name_column["column"] = "name";
|
||||
name_column["value"] = wearablep->mName;
|
||||
list->addElement(element, ADD_BOTTOM);
|
||||
}
|
||||
// Add all root objects to list and keep an id:ptr map
|
||||
std::vector<LLImportObject*>::iterator object_end = mDefaultOptions->mRootObjects.end();
|
||||
for(std::vector<LLImportObject*>::iterator iter = mDefaultOptions->mRootObjects.begin();
|
||||
iter != object_end; ++iter)
|
||||
{
|
||||
LLImportObject* objectp = (*iter);
|
||||
LLUUID id; id.generate();
|
||||
mImportObjectMap[id] = objectp;
|
||||
LLSD element;
|
||||
element["id"] = id;
|
||||
LLSD& check_column = element["columns"][LIST_CHECKED];
|
||||
check_column["column"] = "checked";
|
||||
check_column["type"] = "checkbox";
|
||||
check_column["value"] = true;
|
||||
LLSD& type_column = element["columns"][LIST_TYPE];
|
||||
type_column["column"] = "type";
|
||||
type_column["type"] = "icon";
|
||||
type_column["value"] = "inv_item_object.tga";
|
||||
LLSD& name_column = element["columns"][LIST_NAME];
|
||||
name_column["column"] = "name";
|
||||
name_column["value"] = objectp->mPrimName;
|
||||
list->addElement(element, ADD_BOTTOM);
|
||||
}
|
||||
// Callbacks
|
||||
childSetAction("select_all_btn", onClickSelectAll, this);
|
||||
childSetAction("select_objects_btn", onClickSelectObjects, this);
|
||||
childSetAction("select_wearables_btn", onClickSelectWearables, this);
|
||||
childSetAction("ok_btn", onClickOK, this);
|
||||
childSetAction("cancel_btn", onClickCancel, this);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void LLFloaterXmlImportOptions::onClickSelectAll(void* user_data)
|
||||
{
|
||||
LLFloaterXmlImportOptions* floaterp = (LLFloaterXmlImportOptions*)user_data;
|
||||
LLScrollListCtrl* list = floaterp->getChild<LLScrollListCtrl>("import_list");
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
|
||||
std::vector<LLScrollListItem*>::iterator items_end = items.end();
|
||||
bool new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue());
|
||||
for( ; item_iter != items_end; ++item_iter)
|
||||
{
|
||||
(*item_iter)->getColumn(LIST_CHECKED)->setValue(new_value);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterXmlImportOptions::onClickSelectObjects(void* user_data)
|
||||
{
|
||||
LLFloaterXmlImportOptions* floaterp = (LLFloaterXmlImportOptions*)user_data;
|
||||
LLScrollListCtrl* list = floaterp->getChild<LLScrollListCtrl>("import_list");
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
|
||||
std::vector<LLScrollListItem*>::iterator items_end = items.end();
|
||||
bool new_value = false;
|
||||
for( ; item_iter != items_end; ++item_iter)
|
||||
{
|
||||
if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() == "inv_item_object.tga")
|
||||
{
|
||||
new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(item_iter = items.begin(); item_iter != items_end; ++item_iter)
|
||||
{
|
||||
if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() == "inv_item_object.tga")
|
||||
(*item_iter)->getColumn(LIST_CHECKED)->setValue(new_value);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterXmlImportOptions::onClickSelectWearables(void* user_data)
|
||||
{
|
||||
LLFloaterXmlImportOptions* floaterp = (LLFloaterXmlImportOptions*)user_data;
|
||||
LLScrollListCtrl* list = floaterp->getChild<LLScrollListCtrl>("import_list");
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator item_iter = items.begin();
|
||||
std::vector<LLScrollListItem*>::iterator items_end = items.end();
|
||||
bool new_value = false;
|
||||
for( ; item_iter != items_end; ++item_iter)
|
||||
{
|
||||
if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() != "inv_item_object.tga")
|
||||
{
|
||||
new_value = !((*item_iter)->getColumn(LIST_CHECKED)->getValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(item_iter = items.begin(); item_iter != items_end; ++item_iter)
|
||||
{
|
||||
if(((*item_iter)->getColumn(LIST_TYPE)->getValue()).asString() != "inv_item_object.tga")
|
||||
(*item_iter)->getColumn(LIST_CHECKED)->setValue(new_value);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterXmlImportOptions::onClickOK(void* user_data)
|
||||
{
|
||||
LLFloaterXmlImportOptions* floaterp = (LLFloaterXmlImportOptions*)user_data;
|
||||
LLXmlImportOptions* opt = new LLXmlImportOptions(floaterp->mDefaultOptions);
|
||||
opt->clear();
|
||||
opt->mReplaceTexture = floaterp->childGetValue("upload_textures");
|
||||
LLScrollListCtrl* list = floaterp->getChild<LLScrollListCtrl>("import_list");
|
||||
std::vector<LLScrollListItem*> items = list->getAllData();
|
||||
std::vector<LLScrollListItem*>::iterator item_end = items.end();
|
||||
std::vector<LLImportObject*>::iterator child_end = floaterp->mDefaultOptions->mChildObjects.end();
|
||||
std::list<LLUUID> textures;
|
||||
for(std::vector<LLScrollListItem*>::iterator iter = items.begin(); iter != item_end; ++iter)
|
||||
{
|
||||
if((*iter)->getColumn(LIST_CHECKED)->getValue())
|
||||
{ // checked
|
||||
LLUUID id = (*iter)->getUUID();
|
||||
if(floaterp->mImportWearableMap.find(id) != floaterp->mImportWearableMap.end())
|
||||
{
|
||||
opt->mWearables.push_back(floaterp->mImportWearableMap[id]);
|
||||
if(opt->mReplaceTexture)
|
||||
std::copy(floaterp->mImportWearableMap[id]->mTextures.begin(),floaterp->mImportWearableMap[id]->mTextures.end(),back_inserter(textures));
|
||||
}
|
||||
else // object
|
||||
{
|
||||
LLImportObject* objectp = floaterp->mImportObjectMap[id];
|
||||
|
||||
if(opt->mReplaceTexture)
|
||||
std::copy(objectp->mTextures.begin(),objectp->mTextures.end(),back_inserter(textures));
|
||||
|
||||
opt->mRootObjects.push_back(objectp);
|
||||
// Add child objects
|
||||
for(std::vector<LLImportObject*>::iterator child_iter = floaterp->mDefaultOptions->mChildObjects.begin();
|
||||
child_iter != child_end; ++child_iter)
|
||||
{
|
||||
if((*child_iter)->mParentId == objectp->mId)
|
||||
{
|
||||
if(opt->mReplaceTexture)
|
||||
std::copy((*child_iter)->mTextures.begin(),(*child_iter)->mTextures.end(),back_inserter(textures));
|
||||
opt->mChildObjects.push_back((*child_iter));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(opt->mReplaceTexture)
|
||||
{
|
||||
textures.unique();
|
||||
if(!opt->mAssetDir.empty() && LLFile::isdir(opt->mAssetDir))
|
||||
{
|
||||
opt->mAssetDir.append(gDirUtilp->getDirDelimiter()); //lets add the Delimiter now
|
||||
for(std::list<LLUUID>::iterator itr = textures.begin(); itr != textures.end(); ++itr)
|
||||
{
|
||||
std::string filename = opt->mAssetDir + (*itr).asString() + ".j2c";
|
||||
//llinfos << "Looking texture at " << filename << llendl;
|
||||
if(LLFile::isfile(filename))
|
||||
{
|
||||
//llinfos << "Found texture at " << filename << llendl;
|
||||
LLImportAssetData* data = new LLImportAssetData(filename,(*itr),LLAssetType::AT_TEXTURE);
|
||||
|
||||
opt->mAssets.push_back(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
opt->mKeepPosition = floaterp->childGetValue("keep_position_check");
|
||||
LLXmlImport::import(opt);
|
||||
floaterp->close();
|
||||
}
|
||||
|
||||
void LLFloaterXmlImportOptions::onClickCancel(void* user_data)
|
||||
{
|
||||
LLFloaterXmlImportOptions* floaterp = (LLFloaterXmlImportOptions*)user_data;
|
||||
floaterp->close();
|
||||
}
|
||||
|
||||
LLFloaterImportProgress::LLFloaterImportProgress()
|
||||
: LLFloater("ImportProgress", LLRect(0, 130, 400, 0), "Import progress")
|
||||
{
|
||||
LLLineEditor* line;
|
||||
LLViewBorder* border;
|
||||
|
||||
line = new LLLineEditor(
|
||||
std::string("Uploaded"),
|
||||
LLRect(4, 105, 396, 85),
|
||||
std::string("Uploaded Assets"));
|
||||
line->setEnabled(FALSE);
|
||||
addChild(line);
|
||||
|
||||
border = new LLViewBorder(
|
||||
"UploadedBorder",
|
||||
LLRect(4, 104, 395, 85));
|
||||
addChild(border);
|
||||
|
||||
line = new LLLineEditor(
|
||||
std::string("Created"),
|
||||
LLRect(4, 80, 396, 60),
|
||||
std::string("Created prims"));
|
||||
line->setEnabled(FALSE);
|
||||
addChild(line);
|
||||
|
||||
border = new LLViewBorder(
|
||||
"CreatedBorder",
|
||||
LLRect(4, 79, 395, 60));
|
||||
addChild(border);
|
||||
|
||||
line = new LLLineEditor(
|
||||
std::string("Edited"),
|
||||
LLRect(4, 55, 396, 35),
|
||||
std::string("Edited prims"));
|
||||
line->setEnabled(FALSE);
|
||||
addChild(line);
|
||||
|
||||
border = new LLViewBorder(
|
||||
"EditedBorder",
|
||||
LLRect(4, 54, 395, 35));
|
||||
addChild(border);
|
||||
|
||||
LLButton* button = new LLButton(
|
||||
"CancelButton",
|
||||
LLRect(300, 28, 394, 8));
|
||||
button->setLabel(std::string("Cancel"));
|
||||
button->setEnabled(TRUE);
|
||||
addChild(button);
|
||||
childSetAction("CancelButton", LLXmlImport::Cancel, this);
|
||||
|
||||
sInstance = this;
|
||||
}
|
||||
|
||||
LLFloaterImportProgress::~LLFloaterImportProgress()
|
||||
{
|
||||
sInstance = NULL;
|
||||
}
|
||||
|
||||
void LLFloaterImportProgress::close(bool app_quitting)
|
||||
{
|
||||
LLXmlImport::sImportInProgress = false;
|
||||
LLFloater::close(app_quitting);
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterImportProgress::show()
|
||||
{
|
||||
if(!sInstance)
|
||||
sInstance = new LLFloaterImportProgress();
|
||||
sInstance->open();
|
||||
sInstance->center();
|
||||
}
|
||||
|
||||
// static
|
||||
void LLFloaterImportProgress::update()
|
||||
{
|
||||
if(sInstance)
|
||||
{
|
||||
LLFloaterImportProgress* floater = sInstance;
|
||||
|
||||
int upload_goal = (int)LLXmlImport::sTotalAssets;
|
||||
int upload_done = LLXmlImport::sUploadedAssets;
|
||||
F32 upload_width = F32(390.f / F32(upload_goal));
|
||||
upload_width *= F32(upload_done);
|
||||
bool upload_finished = upload_done >= upload_goal;
|
||||
|
||||
int create_goal = (int)LLXmlImport::sPrims.size();
|
||||
int create_done = create_goal - LLXmlImport::sPrimsNeeded;
|
||||
F32 create_width = F32(390.f / F32(create_goal));
|
||||
create_width *= F32(create_done);
|
||||
bool create_finished = create_done >= create_goal;
|
||||
|
||||
int edit_goal = create_goal;
|
||||
int edit_done = LLXmlImport::sPrimIndex;
|
||||
F32 edit_width = F32(390.f / F32(edit_goal));
|
||||
edit_width *= edit_done;
|
||||
bool edit_finished = edit_done >= edit_goal;
|
||||
|
||||
int attach_goal = (int)LLXmlImport::sId2attachpt.size();
|
||||
int attach_done = LLXmlImport::sAttachmentsDone;
|
||||
F32 attach_width = F32(390.f / F32(attach_goal));
|
||||
attach_width *= F32(attach_done);
|
||||
bool attach_finished = attach_done >= attach_goal;
|
||||
|
||||
bool all_finished = upload_finished && create_finished && edit_finished && attach_finished;
|
||||
|
||||
std::string title;
|
||||
title.assign(all_finished ? "Imported " : "Importing ");
|
||||
title.append(LLXmlImport::sXmlImportOptions->mName);
|
||||
if(!all_finished) title.append("...");
|
||||
floater->setTitle(title);
|
||||
|
||||
std::string uploaded_text = llformat("Uploaded %d/%d assets", S32(upload_done), S32(upload_goal));
|
||||
std::string created_text = llformat("Created %d/%d prims", S32(create_done), S32(create_goal));
|
||||
std::string edited_text = llformat("Finished %d/%d prims", edit_done, edit_goal);
|
||||
|
||||
LLLineEditor* text = floater->getChild<LLLineEditor>("Uploaded");
|
||||
text->setText(uploaded_text);
|
||||
|
||||
text = floater->getChild<LLLineEditor>("Created");
|
||||
text->setText(created_text);
|
||||
|
||||
text = floater->getChild<LLLineEditor>("Edited");
|
||||
text->setText(edited_text);
|
||||
|
||||
LLViewBorder* border = floater->getChild<LLViewBorder>("UploadedBorder");
|
||||
border->setRect(LLRect(4, 104, 4 + upload_width, 85));
|
||||
|
||||
border = floater->getChild<LLViewBorder>("CreatedBorder");
|
||||
border->setRect(LLRect(4, 79, 4 + create_width, 60));
|
||||
|
||||
border = floater->getChild<LLViewBorder>("EditedBorder");
|
||||
border->setRect(LLRect(4, 54, 4 + edit_width, 35));
|
||||
|
||||
LLButton* button = floater->getChild<LLButton>("CancelButton");
|
||||
button->setEnabled(!all_finished);
|
||||
}
|
||||
}
|
||||
|
||||
// </edit>
|
||||
@@ -1,51 +0,0 @@
|
||||
// <edit>
|
||||
/**
|
||||
* @file llfloaterimport.h
|
||||
*/
|
||||
|
||||
#ifndef LL_LLFLOATERIMPORT_H
|
||||
#define LL_LLFLOATERIMPORT_H
|
||||
|
||||
#include "llviewerobject.h"
|
||||
#include "llfloater.h"
|
||||
#include "llimportobject.h"
|
||||
|
||||
|
||||
class LLFloaterImportProgress
|
||||
: public LLFloater
|
||||
{
|
||||
public:
|
||||
void close(bool app_quitting);
|
||||
static LLFloaterImportProgress* sInstance;
|
||||
static void show();
|
||||
static void update();
|
||||
private:
|
||||
LLFloaterImportProgress();
|
||||
virtual ~LLFloaterImportProgress();
|
||||
};
|
||||
|
||||
|
||||
class LLFloaterXmlImportOptions : public LLFloater
|
||||
{
|
||||
public:
|
||||
LLFloaterXmlImportOptions(LLXmlImportOptions* default_options);
|
||||
BOOL postBuild();
|
||||
LLXmlImportOptions* mDefaultOptions;
|
||||
std::map<LLUUID, LLImportWearable*> mImportWearableMap;
|
||||
std::map<LLUUID, LLImportObject*> mImportObjectMap;
|
||||
private:
|
||||
enum LIST_COLUMN_ORDER
|
||||
{
|
||||
LIST_CHECKED,
|
||||
LIST_TYPE,
|
||||
LIST_NAME,
|
||||
};
|
||||
static void onClickSelectAll(void* user_data);
|
||||
static void onClickSelectObjects(void* user_data);
|
||||
static void onClickSelectWearables(void* user_data);
|
||||
static void onClickOK(void* user_data);
|
||||
static void onClickCancel(void* user_data);
|
||||
};
|
||||
|
||||
#endif
|
||||
// </edit>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,120 +0,0 @@
|
||||
// <edit>
|
||||
/**
|
||||
* @file llimportobject.h
|
||||
*/
|
||||
|
||||
#ifndef LL_LLIMPORTOBJECT_H
|
||||
#define LL_LLIMPORTOBJECT_H
|
||||
|
||||
#include "llviewerobject.h"
|
||||
#include "llfloater.h"
|
||||
#include "llvoavatardefines.h"
|
||||
|
||||
class LLImportAssetData
|
||||
{
|
||||
public:
|
||||
LLImportAssetData(std::string infilename,LLUUID inassetid,LLAssetType::EType intype);
|
||||
U32 localid;
|
||||
LLAssetType::EType type;
|
||||
LLInventoryType::EType inv_type;
|
||||
EWearableType wear_type;
|
||||
LLTransactionID tid;
|
||||
LLUUID assetid;
|
||||
LLUUID folderid;
|
||||
LLUUID oldassetid;
|
||||
std::string name;
|
||||
std::string description;
|
||||
std::string filename;
|
||||
};
|
||||
|
||||
class LLImportWearable
|
||||
{
|
||||
public:
|
||||
std::string mName;
|
||||
int mType;
|
||||
std::string mData;
|
||||
LLSD mOrginalLLSD;
|
||||
LLImportWearable(LLSD sd);
|
||||
std::list<LLUUID> mTextures;
|
||||
void replaceTextures(std::map<LLUUID,LLUUID> textures_replace);
|
||||
};
|
||||
|
||||
class LLImportObject : public LLViewerObject
|
||||
{
|
||||
public:
|
||||
//LLImportObject(std::string id, std::string parentId);
|
||||
LLImportObject(std::string id, LLSD prim);
|
||||
std::string mId;
|
||||
std::string mParentId;
|
||||
std::string mPrimName;
|
||||
bool importIsAttachment;
|
||||
U32 importAttachPoint;
|
||||
LLVector3 importAttachPos;
|
||||
LLQuaternion importAttachRot;
|
||||
std::list<LLUUID> mTextures;
|
||||
};
|
||||
|
||||
class LLXmlImportOptions
|
||||
{
|
||||
friend bool operator==(const LLXmlImportOptions &a, const LLXmlImportOptions &b);
|
||||
friend bool operator!=(const LLXmlImportOptions &a, const LLXmlImportOptions &b);
|
||||
public:
|
||||
LLXmlImportOptions(LLXmlImportOptions* options);
|
||||
LLXmlImportOptions(std::string filename);
|
||||
LLXmlImportOptions(LLSD llsd);
|
||||
virtual ~LLXmlImportOptions();
|
||||
void clear();
|
||||
void init(LLSD llsd);
|
||||
std::string mName;
|
||||
//LLSD mLLSD;
|
||||
std::string mAssetDir;
|
||||
std::vector<LLImportAssetData*> mAssets;
|
||||
std::vector<LLImportObject*> mRootObjects;
|
||||
std::vector<LLImportObject*> mChildObjects;
|
||||
std::vector<LLImportWearable*> mWearables;
|
||||
BOOL mKeepPosition;
|
||||
LLViewerObject* mSupplier;
|
||||
BOOL mReplaceTexture;
|
||||
protected:
|
||||
LLUUID mID;
|
||||
};
|
||||
|
||||
|
||||
class LLXmlImport
|
||||
{
|
||||
public:
|
||||
static void import(LLXmlImportOptions* import_options);
|
||||
static void onNewPrim(LLViewerObject* object);
|
||||
static void onNewItem(LLViewerInventoryItem* item);
|
||||
static void onNewAttachment(LLViewerObject* object);
|
||||
static void Cancel(void* user_data);
|
||||
static void rez_supply();
|
||||
static void finish_init();
|
||||
static void finish_link();
|
||||
|
||||
static bool sImportInProgress;
|
||||
static bool sImportHasAttachments;
|
||||
static LLUUID sFolderID;
|
||||
static LLViewerObject* sSupplyParams;
|
||||
static int sPrimsNeeded;
|
||||
static std::vector<LLImportObject*> sPrims; // all prims being imported
|
||||
static std::map<U8, bool> sPt2watch; // attach points that need watching
|
||||
static std::map<std::string, U8> sId2attachpt; // attach points of all attachables
|
||||
static std::map<U8, LLVector3> sPt2attachpos; // positions of all attachables
|
||||
static std::map<U8, LLQuaternion> sPt2attachrot; // rotations of all attachables
|
||||
static std::map<U32, std::queue<U32> > sLinkSets;//Linksets to link.
|
||||
static int sPrimIndex;
|
||||
static int sAttachmentsDone;
|
||||
static std::map<std::string, U32> sId2localid;
|
||||
static std::map<U32, LLVector3> sRootpositions;
|
||||
static std::map<U32, LLQuaternion> sRootrotations;
|
||||
static LLXmlImportOptions* sXmlImportOptions;
|
||||
|
||||
static int sTotalAssets;
|
||||
static int sUploadedAssets;
|
||||
static std::map<LLUUID,LLUUID> sTextureReplace;
|
||||
};
|
||||
|
||||
#endif
|
||||
// </edit>
|
||||
|
||||
@@ -96,7 +96,6 @@
|
||||
#include "llappviewer.h" // System Folders
|
||||
#include "llfloateranimpreview.h" // for reuploads
|
||||
#include "llfloaterimagepreview.h" // for reuploads
|
||||
#include "llimportobject.h" // for disabling options during import
|
||||
//#include "llcheats.h"
|
||||
#include "dofloaterhex.h"
|
||||
#include "hgfloatertexteditor.h"
|
||||
@@ -2397,17 +2396,10 @@ void LLFolderBridge::folderOptionsMenu()
|
||||
// Only enable add/replace outfit for non-default folders.
|
||||
if (!is_default_folder)
|
||||
{
|
||||
// <edit> don't allow attaching stuff during attachment import
|
||||
if(!(LLXmlImport::sImportInProgress && LLXmlImport::sImportHasAttachments))
|
||||
{
|
||||
// </edit>
|
||||
if (gHippoGridManager->getConnectedGrid()->supportsInvLinks())
|
||||
mItems.push_back(std::string("Add To Outfit"));
|
||||
mItems.push_back(std::string("Wear Items"));
|
||||
mItems.push_back(std::string("Replace Outfit"));
|
||||
// <edit>
|
||||
}
|
||||
// </edit>
|
||||
if (gHippoGridManager->getConnectedGrid()->supportsInvLinks())
|
||||
mItems.push_back(std::string("Add To Outfit"));
|
||||
mItems.push_back(std::string("Wear Items"));
|
||||
mItems.push_back(std::string("Replace Outfit"));
|
||||
}
|
||||
mItems.push_back(std::string("Take Off Items"));
|
||||
}
|
||||
@@ -4172,10 +4164,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
|
||||
}
|
||||
else
|
||||
// </edit>
|
||||
// <edit> don't allow attaching objects while importing attachments
|
||||
//if( !isInTrash() )
|
||||
if( !isInTrash() && !(LLXmlImport::sImportInProgress && LLXmlImport::sImportHasAttachments))
|
||||
// </edit>
|
||||
if( !isInTrash() )
|
||||
{
|
||||
items.push_back(std::string("Attach Separator"));
|
||||
items.push_back(std::string("Object Wear"));
|
||||
|
||||
@@ -60,7 +60,6 @@
|
||||
#include "llvoavatar.h"
|
||||
#include "llsdutil.h"
|
||||
// <edit>
|
||||
#include "llimportobject.h"
|
||||
#include "llappviewer.h" // gLostItemsRoot
|
||||
// </edit>
|
||||
#include <deque>
|
||||
@@ -1977,10 +1976,6 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
|
||||
if(item)
|
||||
{
|
||||
mItemMap[item->getUUID()] = item;
|
||||
// <edit>
|
||||
if(LLXmlImport::sImportInProgress)
|
||||
LLXmlImport::onNewItem(item);
|
||||
// </edit>
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -93,10 +93,6 @@
|
||||
#include "rlvhandler.h"
|
||||
// [/RLVa:KB]
|
||||
|
||||
// <edit>
|
||||
#include "llfloaterexport.h"
|
||||
// </edit>
|
||||
|
||||
#include "llglheaders.h"
|
||||
|
||||
LLViewerObject* getSelectedParentObject(LLViewerObject *object) ;
|
||||
@@ -4400,10 +4396,6 @@ void LLSelectMgr::processObjectProperties(LLMessageSystem* msg, void** user_data
|
||||
}
|
||||
}
|
||||
|
||||
// <edit> Send to export floaters
|
||||
LLFloaterExport::receiveObjectProperties(id, name, desc);
|
||||
// </edit>
|
||||
|
||||
// Iterate through nodes at end, since it can be on both the regular AND hover list
|
||||
struct f : public LLSelectedNodeFunctor
|
||||
{
|
||||
@@ -4537,7 +4529,7 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use
|
||||
if(sObjectPropertiesFamilyRequests.count(id) != 0 )
|
||||
{
|
||||
// Send to export floaters
|
||||
LLFloaterExport::receiveObjectProperties(id, name, desc);
|
||||
//LLFloaterExport::receiveObjectProperties(id, name, desc);
|
||||
// We got the reply, so remove the object from the list of pending requests
|
||||
sObjectPropertiesFamilyRequests.erase(id);
|
||||
}
|
||||
|
||||
@@ -62,8 +62,6 @@
|
||||
#include "llsdutil.h"
|
||||
// <edit>
|
||||
#include "lllocalinventory.h"
|
||||
#include "llfloaterimport.h"
|
||||
#include "llfloaterexport.h"
|
||||
#include "llfloaterexploreanimations.h"
|
||||
#include "llfloaterexploresounds.h"
|
||||
#include "llfloaterblacklist.h"
|
||||
@@ -113,7 +111,6 @@
|
||||
#include "llfloatercustomize.h"
|
||||
#include "llfloaterdaycycle.h"
|
||||
//#include "llfloaterdickdongs.h" No need for the custom floater right now, I think. -HgB
|
||||
#include "ascentuploadbrowser.h" //New customer floater attempts
|
||||
#include "llfloaterdirectory.h"
|
||||
#include "llfloatereditui.h"
|
||||
#include "llfloaterchatterbox.h"
|
||||
@@ -2538,64 +2535,6 @@ class LLObjectCopyUUID : public view_listener_t
|
||||
}
|
||||
};
|
||||
|
||||
class LLObjectEnableImport : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
||||
bool new_value = (object != NULL);
|
||||
if(object)
|
||||
{
|
||||
if(!object->permCopy())
|
||||
new_value = false;
|
||||
else if(!object->permModify())
|
||||
new_value = false;
|
||||
else if(!object->permMove())
|
||||
new_value = false;
|
||||
else if(object->numChildren() != 0)
|
||||
new_value = false;
|
||||
else if(object->getParent())
|
||||
new_value = false;
|
||||
}
|
||||
gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLObjectImport : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
LLViewerObject* object = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
|
||||
bool new_value = (object != NULL);
|
||||
if(object)
|
||||
{
|
||||
if(!object->permCopy())
|
||||
new_value = false;
|
||||
else if(!object->permModify())
|
||||
new_value = false;
|
||||
else if(!object->permMove())
|
||||
new_value = false;
|
||||
else if(object->numChildren() != 0)
|
||||
new_value = false;
|
||||
else if(object->getParent())
|
||||
new_value = false;
|
||||
}
|
||||
if(new_value == false) return true;
|
||||
|
||||
LLFilePicker& picker = LLFilePicker::instance();
|
||||
if (!picker.getOpenFile(LLFilePicker::FFLOAD_XML))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
std::string file_name = picker.getFirstFile();
|
||||
LLXmlImportOptions* options = new LLXmlImportOptions(file_name);
|
||||
options->mSupplier = object;
|
||||
new LLFloaterXmlImportOptions(options);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLObjectData : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
@@ -6597,10 +6536,6 @@ class LLShowFloater : public view_listener_t
|
||||
{
|
||||
LLFloaterPerms::toggleInstance(LLSD());
|
||||
}
|
||||
else if (floater_name == "ascentuploadbrowser")
|
||||
{
|
||||
ASFloaterUploadBrowser::show(NULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -7420,10 +7355,6 @@ class LLObjectEnableWear : public view_listener_t
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
bool is_wearable = object_selected_and_point_valid(NULL);
|
||||
// <edit> Don't allow attaching objects while importing attachments
|
||||
if(LLXmlImport::sImportInProgress && LLXmlImport::sImportHasAttachments)
|
||||
is_wearable = false;
|
||||
// </edit>
|
||||
gMenuHolder->findControl(userdata["control"].asString())->setValue(is_wearable);
|
||||
return TRUE;
|
||||
}
|
||||
@@ -10452,7 +10383,7 @@ void initialize_menus()
|
||||
addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse");
|
||||
addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse");
|
||||
// <edit>
|
||||
addMenu(new LLObjectImport(), "Object.Import");
|
||||
//addMenu(new LLObjectImport(), "Object.Import");
|
||||
addMenu(new LLObjectMeasure(), "Object.Measure");
|
||||
addMenu(new LLObjectData(), "Object.Data");
|
||||
addMenu(new LLScriptCount(), "Object.ScriptCount");
|
||||
@@ -10476,7 +10407,7 @@ void initialize_menus()
|
||||
addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
|
||||
addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
|
||||
// <edit>
|
||||
addMenu(new LLObjectEnableImport(), "Object.EnableImport");
|
||||
//addMenu(new LLObjectEnableImport(), "Object.EnableImport");
|
||||
// </edit>
|
||||
addMenu(new LLObjectEnableMute(), "Object.EnableMute");
|
||||
addMenu(new LLObjectEnableBuy(), "Object.EnableBuy");
|
||||
|
||||
@@ -65,8 +65,6 @@
|
||||
#include "lluploaddialog.h"
|
||||
// <edit>
|
||||
#include "llselectmgr.h"
|
||||
#include "llfloaterimport.h"
|
||||
#include "llfloaterexport.h"
|
||||
#include "llassettype.h"
|
||||
#include "llinventorytype.h"
|
||||
#include "llbvhloader.h"
|
||||
@@ -432,35 +430,6 @@ class LLFileUploadBulk : public view_listener_t
|
||||
}
|
||||
};
|
||||
|
||||
// <edit>
|
||||
class LLFileImportXML : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
LLFilePicker& picker = LLFilePicker::instance();
|
||||
if (!picker.getOpenFile(LLFilePicker::FFLOAD_XML))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
std::string file_name = picker.getFirstFile();
|
||||
new LLFloaterXmlImportOptions(new LLXmlImportOptions(file_name));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class LLFileEnableImportXML : public view_listener_t
|
||||
{
|
||||
bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
|
||||
{
|
||||
bool new_value = !LLXmlImport::sImportInProgress;
|
||||
|
||||
// horrendously opaque, this code
|
||||
gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// </edit>
|
||||
|
||||
void upload_error(const std::string& error_message, const std::string& label, const std::string& filename, const LLSD& args)
|
||||
{
|
||||
llwarns << error_message << llendl;
|
||||
@@ -533,20 +502,8 @@ class LLFileSaveTexture : public view_listener_t
|
||||
LLFloater* top = gFloaterView->getFrontmost();
|
||||
if (top)
|
||||
{
|
||||
// <edit>
|
||||
if(top->canSaveAs())
|
||||
{
|
||||
// </edit>
|
||||
top->saveAs();
|
||||
// <edit>
|
||||
return true;
|
||||
}
|
||||
// </edit>
|
||||
top->saveAs();
|
||||
}
|
||||
// <edit>
|
||||
top = new LLFloaterExport();
|
||||
top->center();
|
||||
// </edit>
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@@ -1348,10 +1305,6 @@ void init_menu_file()
|
||||
(new LLFileUploadSound())->registerListener(gMenuHolder, "File.UploadSound");
|
||||
(new LLFileUploadAnim())->registerListener(gMenuHolder, "File.UploadAnim");
|
||||
(new LLFileUploadBulk())->registerListener(gMenuHolder, "File.UploadBulk");
|
||||
// <edit>
|
||||
(new LLFileImportXML())->registerListener(gMenuHolder, "File.ImportXML");
|
||||
(new LLFileEnableImportXML())->registerListener(gMenuHolder, "File.EnableImportXML");
|
||||
// </edit>
|
||||
(new LLFileCloseWindow())->registerListener(gMenuHolder, "File.CloseWindow");
|
||||
(new LLFileCloseAllWindows())->registerListener(gMenuHolder, "File.CloseAllWindows");
|
||||
(new LLFileEnableCloseWindow())->registerListener(gMenuHolder, "File.EnableCloseWindow");
|
||||
|
||||
@@ -75,10 +75,6 @@
|
||||
|
||||
#include "llappviewer.h"
|
||||
|
||||
// <edit>
|
||||
#include "llimportobject.h"
|
||||
// </edit>
|
||||
|
||||
extern F32 gMinObjectDistance;
|
||||
extern BOOL gAnimateTextures;
|
||||
|
||||
@@ -548,28 +544,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
|
||||
}
|
||||
processUpdateCore(objectp, user_data, i, update_type, NULL, justCreated);
|
||||
}
|
||||
// <edit>
|
||||
if(justCreated && LLXmlImport::sImportInProgress)
|
||||
{
|
||||
if(objectp)
|
||||
{
|
||||
LLViewerObject* parent = (LLViewerObject*)objectp->getParent();
|
||||
if(parent)
|
||||
{
|
||||
if(parent->getID() == gAgent.getID())
|
||||
{
|
||||
LLXmlImport::onNewAttachment(objectp);
|
||||
}
|
||||
}
|
||||
else if( objectp->permYouOwner()
|
||||
&& (objectp->getPCode() == LLXmlImport::sSupplyParams->getPCode())
|
||||
&& (objectp->getScale() == LLXmlImport::sSupplyParams->getScale()))
|
||||
{
|
||||
LLXmlImport::onNewPrim(objectp);
|
||||
}
|
||||
}
|
||||
}
|
||||
// </edit>
|
||||
|
||||
objectp->setLastUpdateType(update_type);
|
||||
objectp->setLastUpdateCached(cached);
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater can_close="true" can_drag_on_left="false" can_minimize="true"
|
||||
can_resize="true" height="400" width="310" min_width="310" min_height="200"
|
||||
name="floater_export" title="Export...">
|
||||
<scroll_list bottom="76" can_resize="true" column_padding="0" draw_heading="false"
|
||||
follows="left|top|bottom|right" left="10" multi_select="true"
|
||||
name="export_list" right="-10" search_column="2" top="-25">
|
||||
<column name="checked" width="20" />
|
||||
<column name="type" width="20" />
|
||||
<column dynamicwidth="true" label="Name" name="name" />
|
||||
<column name="avatarid" visible="false" />
|
||||
</scroll_list>
|
||||
<text bottom="50" left="10" width="100" height="20">Select/Deselect:</text>
|
||||
<button bottom="52" follows="bottom|left" height="20" label="All"
|
||||
left="110" name="select_all_btn" width="40" />
|
||||
<button bottom="52" follows="bottom|left" height="20" label="Objects"
|
||||
left_delta="42" name="select_objects_btn" width="64" />
|
||||
<button bottom="52" follows="bottom|left" height="20" label="Wearables"
|
||||
left_delta="66" name="select_wearables_btn" width="80" />
|
||||
|
||||
<text bottom="25" left="10" width="250" height="20" name="names_progress_text"></text>
|
||||
<check_box bottom="28" left="186" width="250" height="20" name="download_textures" label="Download Textures" initial_value="false"/>
|
||||
|
||||
<button bottom="8" follows="bottom|left" height="20" label="Make Copy"
|
||||
left="158" width="142" name="make_copy_btn" />
|
||||
</floater>
|
||||
@@ -1,24 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater can_close="true" can_drag_on_left="false" can_minimize="false"
|
||||
can_resize="false" height="440" name="Import" title="" width="680">
|
||||
<text height="15" left="10" name="name_label" top="10">
|
||||
Name:
|
||||
</text>
|
||||
<line_editor height="19" max_length="254" name="name_form" width="280" />
|
||||
<text height="15" name="description_label">
|
||||
Description:
|
||||
</text>
|
||||
<line_editor height="19" max_length="254" name="description_form" width="280" />
|
||||
<text height="15" name="preview_label">
|
||||
Files to upload:
|
||||
</text>
|
||||
<scroll_list draw_border="true" height="280" left="10" multi_select="true"
|
||||
name="upload_list" top="-30" width="400" />
|
||||
<button bottom="10" height="20" label="Cancel" left="182" name="cancel_btn" width="64" />
|
||||
<button bottom="10" height="20" label="Upload ([ULOADFEE])" left="31" name="ok_btn"
|
||||
width="110" />
|
||||
<text bottom="356" height="15" left="420" name="preview_label2">
|
||||
Image Preview:
|
||||
</text>
|
||||
<icon height="256" left="420" name="dummy_preview" width="256" />
|
||||
</floater>
|
||||
@@ -1,27 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater can_close="true" can_drag_on_left="false" can_minimize="true"
|
||||
can_resize="true" height="400" width="310" min_width="310" min_height="200"
|
||||
name="floater_import" title="Import Options">
|
||||
<scroll_list bottom="76" can_resize="true" column_padding="0" draw_heading="false"
|
||||
follows="left|top|bottom|right" left="10" multi_select="true"
|
||||
name="import_list" right="-10" search_column="2" top="-25">
|
||||
<column name="checked" width="20" />
|
||||
<column name="type" width="20" />
|
||||
<column dynamicwidth="true" label="Name" name="name" />
|
||||
</scroll_list>
|
||||
<text bottom="50" left="10" width="100" height="20">Select/Deselect:</text>
|
||||
<button bottom="52" follows="bottom|left" height="20" label="All"
|
||||
left="110" name="select_all_btn" width="40" />
|
||||
<button bottom="52" follows="bottom|left" height="20" label="Objects"
|
||||
left_delta="42" name="select_objects_btn" width="64" />
|
||||
<button bottom="52" follows="bottom|left" height="20" label="Wearables"
|
||||
left_delta="66" name="select_wearables_btn" width="80" />
|
||||
|
||||
<check_box bottom="28" left="10" width="250" height="20" name="keep_position_check" label="Use previous region position" initial_value="false"/>
|
||||
<check_box bottom="28" left="186" width="250" height="20" name="upload_textures" label="Upload Textures" initial_value="false"/>
|
||||
|
||||
<button bottom="8" follows="bottom|left" height="20" label="OK"
|
||||
left="10" width="142" name="ok_btn" />
|
||||
<button bottom="8" follows="bottom|left" height="20" label="Cancel"
|
||||
left="158" width="142" name="cancel_btn" />
|
||||
</floater>
|
||||
@@ -1,146 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
|
||||
<floater can_close="true" can_drag_on_left="false" can_minimize="true" can_resize="true"
|
||||
width="650" height="400" min_width="600" min_height="400" max_width="600"
|
||||
name="browser" title="Upload Browser" control_name="UploadBrowserFloater">
|
||||
<combo_box allow_text_entry="false" bottom="-42" follows="left|top" height="18" left="10" max_chars="20"
|
||||
mouse_opaque="true" enabled="true" width="108" name="bookmark_combo" tool_tip="Jump to a common folder">
|
||||
<combo_item name="None" enabled="false" value="None">
|
||||
Bookmarked:
|
||||
</combo_item>
|
||||
</combo_box>
|
||||
<button bottom_delta="0" follows="top|left" height="18" label="+"
|
||||
left_delta="112" name="add_bookmark_button" tool_tip="Add current folder to Bookmarks"
|
||||
width="20" />
|
||||
<button bottom_delta="0" follows="top|left" height="18" label="-"
|
||||
left_delta="22" name="remove_bookmark_button" tool_tip="Remove selected folder from Bookmarks"
|
||||
width="20" />
|
||||
<text type="string" length="50" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-37" drop_shadow_visible="true" enabled="true" follows="left|top"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="12" left="213"
|
||||
mouse_opaque="true" name="drive_label" v_pad="0" width="128">
|
||||
Drive:
|
||||
</text>
|
||||
<combo_box allow_text_entry="false" bottom_delta="-5" follows="left|top" height="18" left_delta="35" max_chars="20"
|
||||
mouse_opaque="true" enabled="true" width="40" name="drive_combo" tool_tip="Switch to another drive">
|
||||
<combo_item name="None" enabled="false" value="None">
|
||||
All
|
||||
</combo_item>
|
||||
<combo_item name="None" enabled="false" value="None">
|
||||
Of
|
||||
</combo_item>
|
||||
<combo_item name="None" enabled="false" value="None">
|
||||
Them
|
||||
</combo_item>
|
||||
</combo_box>
|
||||
<line_editor bottom_delta="-22" follows="left|top" font="SansSerifSmall" height="18" max_length="255"
|
||||
width="255" name="dir_path" left="10" select_all_on_focus_received="true" select_on_focus="true"/>
|
||||
<button bottom_delta="-1" follows="top|left" height="18" label=">" left_delta="257"
|
||||
name="directory_button" tool_tip="Go to this filepath" width="20" />
|
||||
<scroll_list bottom="25" can_resize="true" column_padding="0" draw_heading="true"
|
||||
follows="left|top|bottom" left="7" multi_select="true"
|
||||
name="file_list" width="280" search_column="1"
|
||||
tool_tip="Hold shift or control while clicking to select multiple files"
|
||||
top="-68">
|
||||
<column name="file_type" width="0" />
|
||||
<column name="asset_type" width="0" />
|
||||
<column image="ff_edit_mine_button.tga" name="icon_inventory_type"
|
||||
tool_tip="Inventory Type" width="20" />
|
||||
<column dynamicwidth="true" label="Filename" name="file_name" tool_tip="Filename" />
|
||||
</scroll_list>
|
||||
<text type="string" length="50" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="9" drop_shadow_visible="true" enabled="true" follows="left|bottom"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="12" left="10"
|
||||
mouse_opaque="true" name="filter_label" v_pad="0" width="128">
|
||||
Filter:
|
||||
</text>
|
||||
<combo_box allow_text_entry="false" bottom_delta="-4" follows="left|bottom" height="18" left_delta="30" max_chars="20"
|
||||
mouse_opaque="true" enabled="true" width="108" name="file_filter_combo" tool_tip="Limit results to a specific type">
|
||||
<combo_item name="None" value="None">
|
||||
None
|
||||
</combo_item>
|
||||
<combo_item name="Animation" value="Animation" tool_tip="BVH">
|
||||
Animation
|
||||
</combo_item>
|
||||
<combo_item name="Sound" value="Sound" tool_tip="WAV">
|
||||
Sound
|
||||
</combo_item>
|
||||
<combo_item name="Texture" value="Texture" tool_tip="BMP, JPG, PNG, TGA">
|
||||
Texture
|
||||
</combo_item>
|
||||
</combo_box>
|
||||
<text type="string" length="50" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom_delta="5" drop_shadow_visible="true" enabled="true" follows="left|bottom"
|
||||
font="SansSerifSmall" h_pad="0" halign="right" height="12" left="155"
|
||||
mouse_opaque="true" name="result_label" v_pad="0" width="128">
|
||||
Files: [COUNT]
|
||||
</text>
|
||||
<text type="string" length="50" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-35" drop_shadow_visible="true" enabled="true" follows="left|top"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="12" left="302"
|
||||
mouse_opaque="true" name="name_label" v_pad="0" width="128">
|
||||
Name:
|
||||
</text>
|
||||
<line_editor bottom_delta="-4" follows="left|top" font="SansSerifSmall" height="18" max_length="255"
|
||||
width="214" name="asset_name" left_delta="70" select_all_on_focus_received="true" select_on_focus="true"/>
|
||||
<text type="string" length="50" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="12" left="302"
|
||||
mouse_opaque="true" name="name_label" v_pad="0" width="128">
|
||||
Description:
|
||||
</text>
|
||||
<line_editor bottom_delta="-4" follows="left|top" font="SansSerifSmall" height="18" max_length="255"
|
||||
width="214" name="asset_desc" left_delta="70" select_all_on_focus_received="true" select_on_focus="true"/>
|
||||
<text bottom_delta="-20" follows="top|left" height="12" name="multiple_uploads_label" left="302">
|
||||
Multiple files selected. Total cost is:
|
||||
</text>
|
||||
<text bottom_delta="0" follows="top|left" height="12" name="texture_preview_label" left="302">
|
||||
Preview image as:
|
||||
</text>
|
||||
<combo_box bottom_delta="-5" follows="left|top" height="18" label="Texture Preview"
|
||||
left_delta="120" name="texture_preview_combo" width="164">
|
||||
<combo_item name="Image">
|
||||
Image
|
||||
</combo_item>
|
||||
<combo_item name="Hair">
|
||||
Hair
|
||||
</combo_item>
|
||||
<combo_item name="FemaleHead">
|
||||
Female Head
|
||||
</combo_item>
|
||||
<combo_item name="FemaleUpperBody">
|
||||
Female Upper Body
|
||||
</combo_item>
|
||||
<combo_item name="FemaleLowerBody">
|
||||
Female Lower Body
|
||||
</combo_item>
|
||||
<combo_item name="MaleHead">
|
||||
Male Head
|
||||
</combo_item>
|
||||
<combo_item name="MaleUpperBody">
|
||||
Male Upper Body
|
||||
</combo_item>
|
||||
<combo_item name="MaleLowerBody">
|
||||
Male Lower Body
|
||||
</combo_item>
|
||||
<combo_item name="Skirt">
|
||||
Skirt
|
||||
</combo_item>
|
||||
<combo_item name="SculptedPrim">
|
||||
Sculpted Prim
|
||||
</combo_item>
|
||||
</combo_box>
|
||||
<text bottom="250" follows="top|left" left="302" name="bad_image_text">
|
||||
Unable to read image.
|
||||
|
||||
Try saving image as 24 bit Targa (.tga).
|
||||
</text>
|
||||
<slider bottom_delta="0" can_edit_text="false" enabled="false" width="185" height="16" mouse_opaque="true"
|
||||
decimal_digits="0" increment="1" initial_val="16" left="30" min_val="1.0" max_val="16.0" visible="false"
|
||||
name="timeline" show_text="false" value="1" control_name="AnimationTimelineScrubber"/>
|
||||
<button bottom="9" follows="bottom|left" height="22" label="Upload ([UPLOADFEE])"
|
||||
left="325" name="upload_button" width="120" />
|
||||
<button bottom_delta="0" follows="bottom|left" height="22" label="Temp Upload"
|
||||
left_delta="125" name="upload_button" tool_tip="Uploads a temporary version of the texture. It's free, but has a limited lifespan and area it can be used."
|
||||
width="120" />
|
||||
</tab_container>
|
||||
</floater>
|
||||
@@ -24,17 +24,14 @@
|
||||
mouse_opaque="true" enabled="true" >
|
||||
<on_click function="File.UploadBulk" userdata="" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom="-86" enabled="true" height="19"
|
||||
label="Import XML..." left="0" mouse_opaque="true"
|
||||
name="Import XML" width="243">
|
||||
<on_click function="File.ImportXML" userdata="" />
|
||||
<on_enable function ="File.EnableImportXML" userdata="" />
|
||||
<menu_item_call enabled="false" hidden="false" label="Import" mouse_opaque="true" name="Import">
|
||||
<on_click function="Object.Import" />
|
||||
<on_enable function="Object.EnableImport" />
|
||||
</menu_item_call>
|
||||
<menu_item_call enabled="false" hidden="false" label="Upload Textures + Import" mouse_opaque="true" name="Import">
|
||||
<on_click function="Object.ImportUpload" />
|
||||
<on_enable function="Object.EnableImport" />
|
||||
</menu_item_call>
|
||||
<!--<menu_item_check bottom="-384" enabled="true" height="19" label="Upload Browser" left="0"
|
||||
mouse_opaque="true" name="ascentuploadbrowser" width="211">
|
||||
<on_click function="ShowFloater" userdata="ascentuploadbrowser" />
|
||||
<on_check function="FloaterVisible" userdata="ascentuploadbrowser" />
|
||||
</menu_item_check>-->
|
||||
<menu_item_separator enabled="true" label="-----------" mouse_opaque="true" name="separator" />
|
||||
<menu_item_call enabled="true" label="Set Default Permissions..."
|
||||
mouse_opaque="true" name="perm prefs" >
|
||||
|
||||
Reference in New Issue
Block a user