summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llfloaterautoreplacesettings.cpp108
-rw-r--r--indra/newview/llfloaterautoreplacesettings.h3
-rw-r--r--indra/newview/llfloaterspellchecksettings.cpp16
-rw-r--r--indra/newview/llfloaterspellchecksettings.h1
-rw-r--r--indra/newview/llpreviewscript.cpp48
-rw-r--r--indra/newview/llpreviewscript.h5
-rw-r--r--indra/newview/llviewermenufile.cpp253
-rw-r--r--indra/newview/llviewermenufile.h19
8 files changed, 303 insertions, 150 deletions
diff --git a/indra/newview/llfloaterautoreplacesettings.cpp b/indra/newview/llfloaterautoreplacesettings.cpp
index 5830f2f711..ec05ba924c 100644
--- a/indra/newview/llfloaterautoreplacesettings.cpp
+++ b/indra/newview/llfloaterautoreplacesettings.cpp
@@ -54,6 +54,7 @@
#include "llhost.h"
#include "llassetstorage.h"
#include "roles_constants.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llviewertexteditor.h"
#include <boost/tokenizer.hpp>
@@ -349,62 +350,58 @@ void LLFloaterAutoReplaceSettings::onDeleteEntry()
// called when the Import List button is pressed
void LLFloaterAutoReplaceSettings::onImportList()
{
- LLFilePicker& picker = LLFilePicker::instance();
- if( picker.getOpenFile( LLFilePicker::FFLOAD_XML) )
+ (new LLFilePickerReplyThread(boost::bind(&LLFloaterAutoReplaceSettings::loadListFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
+}
+
+void LLFloaterAutoReplaceSettings::loadListFromFile(const std::vector<std::string>& filenames)
+{
+ llifstream file;
+ file.open(filenames[0].c_str());
+ LLSD newList;
+ if (file.is_open())
{
- llifstream file;
- file.open(picker.getFirstFile().c_str());
- LLSD newList;
- if (file.is_open())
- {
- LLSDSerialize::fromXMLDocument(newList, file);
- }
- file.close();
+ LLSDSerialize::fromXMLDocument(newList, file);
+ }
+ file.close();
- switch ( mSettings.addList(newList) )
- {
- case LLAutoReplaceSettings::AddListOk:
- mSelectedListName = LLAutoReplaceSettings::getListName(newList);
+ switch ( mSettings.addList(newList) )
+ {
+ case LLAutoReplaceSettings::AddListOk:
+ mSelectedListName = LLAutoReplaceSettings::getListName(newList);
- updateListNames();
- updateListNamesControls();
- updateReplacementsList();
- break;
+ updateListNames();
+ updateListNamesControls();
+ updateReplacementsList();
+ break;
- case LLAutoReplaceSettings::AddListDuplicateName:
- {
- std::string newName = LLAutoReplaceSettings::getListName(newList);
- LL_WARNS("AutoReplace")<<"name '"<<newName<<"' is in use; prompting for new name"<<LL_ENDL;
- LLSD newPayload;
- newPayload["list"] = newList;
- LLSD args;
- args["DUPNAME"] = newName;
+ case LLAutoReplaceSettings::AddListDuplicateName:
+ {
+ std::string newName = LLAutoReplaceSettings::getListName(newList);
+ LL_WARNS("AutoReplace")<<"name '"<<newName<<"' is in use; prompting for new name"<<LL_ENDL;
+ LLSD newPayload;
+ newPayload["list"] = newList;
+ LLSD args;
+ args["DUPNAME"] = newName;
- LLNotificationsUtil::add("RenameAutoReplaceList", args, newPayload,
+ LLNotificationsUtil::add("RenameAutoReplaceList", args, newPayload,
boost::bind(&LLFloaterAutoReplaceSettings::callbackListNameConflict, this, _1, _2));
- }
- break;
+ }
+ break;
- case LLAutoReplaceSettings::AddListInvalidList:
- LLNotificationsUtil::add("InvalidAutoReplaceList");
- LL_WARNS("AutoReplace") << "imported list was invalid" << LL_ENDL;
+ case LLAutoReplaceSettings::AddListInvalidList:
+ LLNotificationsUtil::add("InvalidAutoReplaceList");
+ LL_WARNS("AutoReplace") << "imported list was invalid" << LL_ENDL;
- mSelectedListName.clear();
- updateListNames();
- updateListNamesControls();
- updateReplacementsList();
- break;
+ mSelectedListName.clear();
+ updateListNames();
+ updateListNamesControls();
+ updateReplacementsList();
+ break;
- default:
- LL_ERRS("AutoReplace") << "invalid AddListResult" << LL_ENDL;
+ default:
+ LL_ERRS("AutoReplace") << "invalid AddListResult" << LL_ENDL;
- }
-
- }
- else
- {
- LL_DEBUGS("AutoReplace") << "file selection failed for import list" << LL_ENDL;
- }
+ }
}
void LLFloaterAutoReplaceSettings::onNewList()
@@ -539,16 +536,17 @@ void LLFloaterAutoReplaceSettings::onDeleteList()
void LLFloaterAutoReplaceSettings::onExportList()
{
std::string listName=mListNames->getFirstSelected()->getColumn(0)->getValue().asString();
- const LLSD* list = mSettings.exportList(listName);
std::string listFileName = listName + ".xml";
- LLFilePicker& picker = LLFilePicker::instance();
- if( picker.getSaveFile( LLFilePicker::FFSAVE_XML, listFileName) )
- {
- llofstream file;
- file.open(picker.getFirstFile().c_str());
- LLSDSerialize::toPrettyXML(*list, file);
- file.close();
- }
+ (new LLFilePickerReplyThread(boost::bind(&LLFloaterAutoReplaceSettings::saveListToFile, this, _1, listName), LLFilePicker::FFSAVE_XML, listFileName))->getFile();
+}
+
+void LLFloaterAutoReplaceSettings::saveListToFile(const std::vector<std::string>& filenames, std::string listName)
+{
+ llofstream file;
+ const LLSD* list = mSettings.exportList(listName);
+ file.open(filenames[0].c_str());
+ LLSDSerialize::toPrettyXML(*list, file);
+ file.close();
}
void LLFloaterAutoReplaceSettings::onAddEntry()
diff --git a/indra/newview/llfloaterautoreplacesettings.h b/indra/newview/llfloaterautoreplacesettings.h
index 629aea3e3c..2109aa7026 100644
--- a/indra/newview/llfloaterautoreplacesettings.h
+++ b/indra/newview/llfloaterautoreplacesettings.h
@@ -112,6 +112,9 @@ private:
bool selectedListIsLast();
void cleanUp();
+
+ void loadListFromFile(const std::vector<std::string>& filenames);
+ void saveListToFile(const std::vector<std::string>& filenames, std::string listName);
};
#endif // LLFLOATERAUTOREPLACESETTINGS_H
diff --git a/indra/newview/llfloaterspellchecksettings.cpp b/indra/newview/llfloaterspellchecksettings.cpp
index 5124dae147..b87044ef5a 100644
--- a/indra/newview/llfloaterspellchecksettings.cpp
+++ b/indra/newview/llfloaterspellchecksettings.cpp
@@ -30,12 +30,13 @@
#include "llfilepicker.h"
#include "llfloaterreg.h"
#include "llfloaterspellchecksettings.h"
+#include "llnotificationsutil.h"
#include "llscrolllistctrl.h"
#include "llsdserialize.h"
#include "llspellcheck.h"
#include "lltrans.h"
#include "llviewercontrol.h"
-#include "llnotificationsutil.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
#include <boost/algorithm/string.hpp>
@@ -258,13 +259,12 @@ BOOL LLFloaterSpellCheckerImport::postBuild(void)
void LLFloaterSpellCheckerImport::onBtnBrowse()
{
- LLFilePicker& file_picker = LLFilePicker::instance();
- if (!file_picker.getOpenFile(LLFilePicker::FFLOAD_DICTIONARY))
- {
- return;
- }
+ (new LLFilePickerReplyThread(boost::bind(&LLFloaterSpellCheckerImport::importSelectedDictionary, this, _1), LLFilePicker::FFLOAD_DICTIONARY, false))->getFile();
+}
- std::string filepath = file_picker.getFirstFile();
+void LLFloaterSpellCheckerImport::importSelectedDictionary(const std::vector<std::string>& filenames)
+{
+ std::string filepath = filenames[0];
const std::string extension = gDirUtilp->getExtension(filepath);
if ("xcu" == extension)
@@ -277,7 +277,7 @@ void LLFloaterSpellCheckerImport::onBtnBrowse()
}
getChild<LLUICtrl>("dictionary_path")->setValue(filepath);
-
+
mDictionaryDir = gDirUtilp->getDirName(filepath);
mDictionaryBasename = gDirUtilp->getBaseFileName(filepath, true);
getChild<LLUICtrl>("dictionary_name")->setValue(mDictionaryBasename);
diff --git a/indra/newview/llfloaterspellchecksettings.h b/indra/newview/llfloaterspellchecksettings.h
index de59d83f24..f9bbefafb7 100644
--- a/indra/newview/llfloaterspellchecksettings.h
+++ b/indra/newview/llfloaterspellchecksettings.h
@@ -58,6 +58,7 @@ protected:
void onBtnBrowse();
void onBtnCancel();
void onBtnOK();
+ void importSelectedDictionary(const std::vector<std::string>& filenames);
std::string parseXcuFile(const std::string& file_path) const;
std::string mDictionaryDir;
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 945f3c370c..d4eecaffce 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -61,6 +61,7 @@
#include "llselectmgr.h"
#include "llviewerinventory.h"
#include "llviewermenu.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llviewerobject.h"
#include "llviewerobjectlist.h"
#include "llviewerregion.h"
@@ -1202,17 +1203,12 @@ BOOL LLScriptEdCore::handleKeyHere(KEY key, MASK mask)
void LLScriptEdCore::onBtnLoadFromFile( void* data )
{
- LLScriptEdCore* self = (LLScriptEdCore*) data;
-
- // TODO Maybe add a dialogue warning here if the current file has unsaved changes.
- LLFilePicker& file_picker = LLFilePicker::instance();
- if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_SCRIPT ) )
- {
- //File picking cancelled by user, so nothing to do.
- return;
- }
+ (new LLFilePickerReplyThread(boost::bind(&LLScriptEdCore::loadScriptFromFile, _1, data), LLFilePicker::FFLOAD_SCRIPT, false))->getFile();
+}
- std::string filename = file_picker.getFirstFile();
+void LLScriptEdCore::loadScriptFromFile(const std::vector<std::string>& filenames, void* data)
+{
+ std::string filename = filenames[0];
llifstream fin(filename.c_str());
@@ -1220,8 +1216,8 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data )
std::string text;
std::string linetotal;
while (!fin.eof())
- {
- getline(fin,line);
+ {
+ getline(fin, line);
text += line;
if (!fin.eof())
{
@@ -1231,7 +1227,8 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data )
fin.close();
// Only replace the script if there is something to replace with.
- if (text.length() > 0)
+ LLScriptEdCore* self = (LLScriptEdCore*)data;
+ if (self && (text.length() > 0))
{
self->mEditor->selectAll();
LLWString script(utf8str_to_wstring(text));
@@ -1247,16 +1244,21 @@ void LLScriptEdCore::onBtnSaveToFile( void* userdata )
if( self->mSaveCallback )
{
- LLFilePicker& file_picker = LLFilePicker::instance();
- if( file_picker.getSaveFile( LLFilePicker::FFSAVE_SCRIPT, self->mScriptName ) )
- {
- std::string filename = file_picker.getFirstFile();
- std::string scriptText=self->mEditor->getText();
- llofstream fout(filename.c_str());
- fout<<(scriptText);
- fout.close();
- self->mSaveCallback( self->mUserdata, FALSE );
- }
+ (new LLFilePickerReplyThread(boost::bind(&LLScriptEdCore::saveScriptToFile, _1, userdata), LLFilePicker::FFSAVE_SCRIPT, self->mScriptName))->getFile();
+ }
+}
+
+void LLScriptEdCore::saveScriptToFile(const std::vector<std::string>& filenames, void* data)
+{
+ LLScriptEdCore* self = (LLScriptEdCore*)data;
+ if (self)
+ {
+ std::string filename = filenames[0];
+ std::string scriptText = self->mEditor->getText();
+ llofstream fout(filename.c_str());
+ fout << (scriptText);
+ fout.close();
+ self->mSaveCallback(self->mUserdata, FALSE);
}
}
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index a185d85889..69cf9d9158 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -109,7 +109,10 @@ public:
static void onBtnInsertSample(void*);
static void onBtnInsertFunction(LLUICtrl*, void*);
static void onBtnLoadFromFile(void*);
- static void onBtnSaveToFile(void*);
+ static void onBtnSaveToFile(void*);
+
+ static void loadScriptFromFile(const std::vector<std::string>& filenames, void* data);
+ static void saveScriptToFile(const std::vector<std::string>& filenames, void* data);
static bool enableSaveToFileMenu(void* userdata);
static bool enableLoadFromFileMenu(void* userdata);
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 8160a3a139..f676519153 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -203,6 +203,40 @@ void LLFilePickerThread::clearDead()
}
}
+LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple)
+ : LLFilePickerThread(filter, get_multiple),
+ mLoadFilter(filter),
+ mSaveFilter(LLFilePicker::FFSAVE_ALL),
+ mFilePickedSignal(NULL)
+{
+ mFilePickedSignal = new file_picked_signal_t();
+ mFilePickedSignal->connect(cb);
+}
+
+LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name)
+ : LLFilePickerThread(filter, proposed_name),
+ mLoadFilter(LLFilePicker::FFLOAD_ALL),
+ mSaveFilter(filter),
+ mFilePickedSignal(NULL)
+{
+ mFilePickedSignal = new file_picked_signal_t();
+ mFilePickedSignal->connect(cb);
+}
+
+LLFilePickerReplyThread::~LLFilePickerReplyThread()
+{
+ delete mFilePickedSignal;
+}
+
+void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames)
+{
+ if (filenames.empty()) return;
+
+ if (mFilePickedSignal)
+ {
+ (*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter);
+ }
+}
//============================================================================
@@ -249,6 +283,150 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter)
}
}
+
+const bool check_file_extension(const std::string& filename, LLFilePicker::ELoadFilter type)
+{
+ std::string ext = gDirUtilp->getExtension(filename);
+
+ //strincmp doesn't like NULL pointers
+ if (ext.empty())
+ {
+ std::string short_name = gDirUtilp->getBaseFileName(filename);
+
+ // No extension
+ LLSD args;
+ args["FILE"] = short_name;
+ LLNotificationsUtil::add("NoFileExtension", args);
+ return false;
+ }
+ else
+ {
+ //so there is an extension
+ //loop over the valid extensions and compare to see
+ //if the extension is valid
+
+ //now grab the set of valid file extensions
+ std::string valid_extensions = build_extensions_string(type);
+
+ BOOL ext_valid = FALSE;
+
+ typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+ boost::char_separator<char> sep(" ");
+ tokenizer tokens(valid_extensions, sep);
+ tokenizer::iterator token_iter;
+
+ //now loop over all valid file extensions
+ //and compare them to the extension of the file
+ //to be uploaded
+ for (token_iter = tokens.begin();
+ token_iter != tokens.end() && ext_valid != TRUE;
+ ++token_iter)
+ {
+ const std::string& cur_token = *token_iter;
+
+ if (cur_token == ext || cur_token == "*.*")
+ {
+ //valid extension
+ //or the acceptable extension is any
+ ext_valid = TRUE;
+ }
+ }//end for (loop over all tokens)
+
+ if (ext_valid == FALSE)
+ {
+ //should only get here if the extension exists
+ //but is invalid
+ LLSD args;
+ args["EXTENSION"] = ext;
+ args["VALIDS"] = valid_extensions;
+ LLNotificationsUtil::add("InvalidFileExtension", args);
+ return false;
+ }
+ }//end else (non-null extension)
+ return true;
+}
+
+const void upload_single_file(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type)
+{
+ std::string filename = filenames[0];
+ if (!check_file_extension(filename, type)) return;
+
+ if (!filename.empty())
+ {
+ if (type == LLFilePicker::FFLOAD_WAV)
+ {
+ // pre-qualify wavs to make sure the format is acceptable
+ std::string error_msg;
+ if (check_for_invalid_wav_formats(filename, error_msg))
+ {
+ LL_INFOS() << error_msg << ": " << filename << LL_ENDL;
+ LLSD args;
+ args["FILE"] = filename;
+ LLNotificationsUtil::add(error_msg, args);
+ return;
+ }
+ else
+ {
+ LLFloaterReg::showInstance("upload_sound", LLSD(filename));
+ }
+ }
+ if (type == LLFilePicker::FFLOAD_IMAGE)
+ {
+ LLFloaterReg::showInstance("upload_image", LLSD(filename));
+ }
+ if (type == LLFilePicker::FFLOAD_ANIM)
+ {
+ if (filename.rfind(".anim") != std::string::npos)
+ {
+ LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename));
+ }
+ else
+ {
+ LLFloaterReg::showInstance("upload_anim_bvh", LLSD(filename));
+ }
+ }
+ }
+ return;
+}
+
+
+const void upload_bulk(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter type)
+{
+ // TODO:
+ // Check user balance for entire cost
+ // Charge user entire cost
+ // Loop, uploading
+ // If an upload fails, refund the user for that one
+ //
+ // Also fix single upload to charge first, then refund
+
+ S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
+ for (std::vector<std::string>::const_iterator in_iter = filenames.begin(); in_iter != filenames.end(); ++in_iter)
+ {
+ std::string filename = (*in_iter);
+ if (!check_file_extension(filename, type)) continue;
+
+ std::string name = gDirUtilp->getBaseFileName(filename, true);
+ std::string asset_name = name;
+ LLStringUtil::replaceNonstandardASCII(asset_name, '?');
+ LLStringUtil::replaceChar(asset_name, '|', '?');
+ LLStringUtil::stripNonprintable(asset_name);
+ LLStringUtil::trim(asset_name);
+
+ LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
+ filename,
+ asset_name,
+ asset_name, 0,
+ LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ expected_upload_cost));
+
+ upload_new_resource(uploadInfo, NULL, NULL);
+ }
+}
+
/**
char* upload_pick(void* data)
@@ -369,12 +547,12 @@ class LLFileUploadImage : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- std::string filename = upload_pick((void *)LLFilePicker::FFLOAD_IMAGE);
- if (!filename.empty())
+ if (gAgentCamera.cameraMouselook())
{
- LLFloaterReg::showInstance("upload_image", LLSD(filename));
+ gAgentCamera.changeCameraToDefault();
}
- return TRUE;
+ (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_IMAGE, false))->getFile();
+ return true;
}
};
@@ -396,11 +574,11 @@ class LLFileUploadSound : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- std::string filename = upload_pick((void*)LLFilePicker::FFLOAD_WAV);
- if (!filename.empty())
+ if (gAgentCamera.cameraMouselook())
{
- LLFloaterReg::showInstance("upload_sound", LLSD(filename));
+ gAgentCamera.changeCameraToDefault();
}
+ (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_WAV, false))->getFile();
return true;
}
};
@@ -409,18 +587,11 @@ class LLFileUploadAnim : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- const std::string filename = upload_pick((void*)LLFilePicker::FFLOAD_ANIM);
- if (!filename.empty())
+ if (gAgentCamera.cameraMouselook())
{
- if (filename.rfind(".anim") != std::string::npos)
- {
- LLFloaterReg::showInstance("upload_anim_anim", LLSD(filename));
- }
- else
- {
- LLFloaterReg::showInstance("upload_anim_bvh", LLSD(filename));
- }
+ gAgentCamera.changeCameraToDefault();
}
+ (new LLFilePickerReplyThread(boost::bind(&upload_single_file, _1, _2), LLFilePicker::FFLOAD_ANIM, false))->getFile();
return true;
}
};
@@ -429,55 +600,11 @@ class LLFileUploadBulk : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
{
- if( gAgentCamera.cameraMouselook() )
+ if (gAgentCamera.cameraMouselook())
{
gAgentCamera.changeCameraToDefault();
}
-
- // TODO:
- // Check extensions for uploadability, cost
- // Check user balance for entire cost
- // Charge user entire cost
- // Loop, uploading
- // If an upload fails, refund the user for that one
- //
- // Also fix single upload to charge first, then refund
-
- LLFilePicker& picker = LLFilePicker::instance();
- if (picker.getMultipleOpenFiles())
- {
- std::string filename = picker.getFirstFile();
- S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
-
- while (!filename.empty())
- {
- std::string name = gDirUtilp->getBaseFileName(filename, true);
-
- std::string asset_name = name;
- LLStringUtil::replaceNonstandardASCII( asset_name, '?' );
- LLStringUtil::replaceChar(asset_name, '|', '?');
- LLStringUtil::stripNonprintable(asset_name);
- LLStringUtil::trim(asset_name);
-
- LLResourceUploadInfo::ptr_t uploadInfo(new LLNewFileResourceUploadInfo(
- filename,
- asset_name,
- asset_name, 0,
- LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms("Uploads"),
- LLFloaterPerms::getGroupPerms("Uploads"),
- LLFloaterPerms::getEveryonePerms("Uploads"),
- expected_upload_cost));
-
- upload_new_resource(uploadInfo, NULL, NULL);
-
- filename = picker.getNextFile();
- }
- }
- else
- {
- LL_INFOS() << "Couldn't import objects from file" << LL_ENDL;
- }
+ (new LLFilePickerReplyThread(boost::bind(&upload_bulk, _1, _2), LLFilePicker::FFLOAD_ALL, true))->getFile();
return true;
}
};
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 3e23940c3f..15bbdd1e2d 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -107,4 +107,23 @@ public:
};
+class LLFilePickerReplyThread : public LLFilePickerThread
+{
+public:
+
+ typedef boost::signals2::signal<void(const std::vector<std::string>& filenames, LLFilePicker::ELoadFilter load_filter, LLFilePicker::ESaveFilter save_filter)> file_picked_signal_t;
+
+ LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple);
+ LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name);
+ ~LLFilePickerReplyThread();
+
+ virtual void notify(const std::vector<std::string>& filenames);
+
+private:
+ LLFilePicker::ELoadFilter mLoadFilter;
+ LLFilePicker::ESaveFilter mSaveFilter;
+ file_picked_signal_t* mFilePickedSignal;
+};
+
+
#endif