summaryrefslogtreecommitdiff
path: root/indra
diff options
context:
space:
mode:
authormaxim_productengine <mnikolenko@productengine.com>2018-06-12 17:45:55 +0300
committermaxim_productengine <mnikolenko@productengine.com>2018-06-12 17:45:55 +0300
commit1a014427a257ba9ba78ab173fc5f2f9621d768a1 (patch)
treee295ba43795c47b8a59fe5a2f22b2b2c86023146 /indra
parent1d3266910c5fbcc3c811cf82e0ebfbc7234f8df0 (diff)
MAINT-8727 FIXED Saving snapshot will cause disconnect if you do not choose path in File picker quickly
Diffstat (limited to 'indra')
-rw-r--r--indra/newview/llfloatersnapshot.cpp10
-rw-r--r--indra/newview/llfloatersnapshot.h4
-rw-r--r--indra/newview/lloutfitgallery.cpp114
-rw-r--r--indra/newview/lloutfitgallery.h1
-rw-r--r--indra/newview/llpanelsnapshotlocal.cpp28
-rw-r--r--indra/newview/llsnapshotlivepreview.cpp46
-rw-r--r--indra/newview/llsnapshotlivepreview.h9
-rw-r--r--indra/newview/llviewermenufile.cpp34
-rw-r--r--indra/newview/llviewermenufile.h5
-rw-r--r--indra/newview/llviewerwindow.cpp119
-rw-r--r--indra/newview/llviewerwindow.h8
11 files changed, 206 insertions, 172 deletions
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 156b2ba7b1..c08aaf3f50 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -1309,17 +1309,15 @@ void LLFloaterSnapshot::saveTexture()
previewp->saveTexture();
}
-BOOL LLFloaterSnapshot::saveLocal()
+void LLFloaterSnapshot::saveLocal(const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
LL_DEBUGS() << "saveLocal" << LL_ENDL;
LLSnapshotLivePreview* previewp = getPreviewView();
- if (!previewp)
+ llassert(previewp != NULL);
+ if (previewp)
{
- llassert(previewp != NULL);
- return FALSE;
+ previewp->saveLocal(success_cb, failure_cb);
}
-
- return previewp->saveLocal();
}
void LLFloaterSnapshotBase::postSave()
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index 698273ac90..bcba14d63d 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -156,7 +156,9 @@ public:
static LLFloaterSnapshot* getInstance();
static LLFloaterSnapshot* findInstance();
/*virtual*/ void saveTexture();
- BOOL saveLocal();
+
+ typedef boost::signals2::signal<void(void)> snapshot_saved_signal_t;
+ void saveLocal(const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
static void setAgentEmail(const std::string& email);
BOOL isWaitingState();
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index dc3b153da2..a90a29a731 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1166,72 +1166,72 @@ void LLOutfitGallery::refreshTextures(const LLUUID& category_id)
void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
{
- outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
- if (outfit_it == mOutfitMap.end() || outfit_it->first.isNull())
- {
- return;
- }
+ outfit_map_t::iterator outfit_it = mOutfitMap.find(outfit_id);
+ if (outfit_it == mOutfitMap.end() || outfit_it->first.isNull())
+ {
+ return;
+ }
+ (new LLFilePickerReplyThread(boost::bind(&LLOutfitGallery::uploadOutfitImage, this, _1, outfit_id), LLFilePicker::FFLOAD_IMAGE, false))->getFile();
+}
- LLFilePicker& picker = LLFilePicker::instance();
- if (picker.getOpenFile(LLFilePicker::FFLOAD_IMAGE))
+void LLOutfitGallery::uploadOutfitImage(const std::vector<std::string>& filenames, LLUUID outfit_id)
+{
+ std::string filename = filenames[0];
+ LLLocalBitmap* unit = new LLLocalBitmap(filename);
+ if (unit->getValid())
{
- std::string filename = picker.getFirstFile();
- LLLocalBitmap* unit = new LLLocalBitmap(filename);
- if (unit->getValid())
+ std::string exten = gDirUtilp->getExtension(filename);
+ U32 codec = LLImageBase::getCodecFromExtension(exten);
+
+ LLImageDimensionsInfo image_info;
+ std::string image_load_error;
+ if (!image_info.load(filename, codec))
{
- std::string exten = gDirUtilp->getExtension(filename);
- U32 codec = LLImageBase::getCodecFromExtension(exten);
+ image_load_error = image_info.getLastError();
+ }
- LLImageDimensionsInfo image_info;
- std::string image_load_error;
- if (!image_info.load(filename, codec))
- {
- image_load_error = image_info.getLastError();
- }
+ S32 max_width = MAX_OUTFIT_PHOTO_WIDTH;
+ S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT;
- S32 max_width = MAX_OUTFIT_PHOTO_WIDTH;
- S32 max_height = MAX_OUTFIT_PHOTO_HEIGHT;
+ if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
+ {
+ LLStringUtil::format_map_t args;
+ args["WIDTH"] = llformat("%d", max_width);
+ args["HEIGHT"] = llformat("%d", max_height);
- if ((image_info.getWidth() > max_width) || (image_info.getHeight() > max_height))
- {
- LLStringUtil::format_map_t args;
- args["WIDTH"] = llformat("%d", max_width);
- args["HEIGHT"] = llformat("%d", max_height);
+ image_load_error = LLTrans::getString("outfit_photo_load_dimensions_error", args);
+ }
- image_load_error = LLTrans::getString("outfit_photo_load_dimensions_error", args);
- }
+ if (!image_load_error.empty())
+ {
+ LLSD subst;
+ subst["REASON"] = image_load_error;
+ LLNotificationsUtil::add("OutfitPhotoLoadError", subst);
+ return;
+ }
- if (!image_load_error.empty())
- {
- LLSD subst;
- subst["REASON"] = image_load_error;
- LLNotificationsUtil::add("OutfitPhotoLoadError", subst);
- return;
- }
+ S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
+ void *nruserdata = NULL;
+ nruserdata = (void *)&outfit_id;
- S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
- void *nruserdata = NULL;
- nruserdata = (void *)&outfit_id;
-
- LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id);
- if (!outfit_cat) return;
- updateSnapshotFolderObserver();
- checkRemovePhoto(outfit_id);
- std::string upload_pending_name = outfit_id.asString();
- std::string upload_pending_desc = "";
- LLAssetStorage::LLStoreAssetCallback callback = NULL;
- LLUUID photo_id = upload_new_resource(filename, // file
- upload_pending_name,
- upload_pending_desc,
- 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
- LLFloaterPerms::getNextOwnerPerms("Uploads"),
- LLFloaterPerms::getGroupPerms("Uploads"),
- LLFloaterPerms::getEveryonePerms("Uploads"),
- upload_pending_name, callback, expected_upload_cost, nruserdata);
- mOutfitLinkPending = outfit_id;
- }
- delete unit;
- }
+ LLViewerInventoryCategory *outfit_cat = gInventory.getCategory(outfit_id);
+ if (!outfit_cat) return;
+ updateSnapshotFolderObserver();
+ checkRemovePhoto(outfit_id);
+ std::string upload_pending_name = outfit_id.asString();
+ std::string upload_pending_desc = "";
+ LLAssetStorage::LLStoreAssetCallback callback = NULL;
+ LLUUID photo_id = upload_new_resource(filename, // file
+ upload_pending_name,
+ upload_pending_desc,
+ 0, LLFolderType::FT_NONE, LLInventoryType::IT_NONE,
+ LLFloaterPerms::getNextOwnerPerms("Uploads"),
+ LLFloaterPerms::getGroupPerms("Uploads"),
+ LLFloaterPerms::getEveryonePerms("Uploads"),
+ upload_pending_name, callback, expected_upload_cost, nruserdata);
+ mOutfitLinkPending = outfit_id;
+ }
+ delete unit;
}
void LLOutfitGallery::linkPhotoToOutfit(LLUUID photo_id, LLUUID outfit_id)
diff --git a/indra/newview/lloutfitgallery.h b/indra/newview/lloutfitgallery.h
index 383924a7d6..6dd8a6298f 100644
--- a/indra/newview/lloutfitgallery.h
+++ b/indra/newview/lloutfitgallery.h
@@ -130,6 +130,7 @@ protected:
private:
void loadPhotos();
void uploadPhoto(LLUUID outfit_id);
+ void uploadOutfitImage(const std::vector<std::string>& filenames, LLUUID outfit_id);
void updateSnapshotFolderObserver();
LLUUID getPhotoAssetId(const LLUUID& outfit_id);
LLUUID getDefaultPhoto();
diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp
index 77378f8092..57c5915da2 100644
--- a/indra/newview/llpanelsnapshotlocal.cpp
+++ b/indra/newview/llpanelsnapshotlocal.cpp
@@ -65,6 +65,9 @@ private:
void onFormatComboCommit(LLUICtrl* ctrl);
void onQualitySliderCommit(LLUICtrl* ctrl);
void onSaveFlyoutCommit(LLUICtrl* ctrl);
+
+ void LLPanelSnapshotLocal::onLocalSaved();
+ void LLPanelSnapshotLocal::onLocalCanceled();
};
static LLPanelInjector<LLPanelSnapshotLocal> panel_class("llpanelsnapshotlocal");
@@ -164,19 +167,22 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl)
LLFloaterSnapshot* floater = LLFloaterSnapshot::getInstance();
floater->notify(LLSD().with("set-working", true));
- BOOL saved = floater->saveLocal();
- if (saved)
- {
- mSnapshotFloater->postSave();
- floater->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
- }
- else
- {
- cancel();
- floater->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "local")));
- }
+ floater->saveLocal((boost::bind(&LLPanelSnapshotLocal::onLocalSaved, this)), (boost::bind(&LLPanelSnapshotLocal::onLocalCanceled, this)));
+}
+
+void LLPanelSnapshotLocal::onLocalSaved()
+{
+ mSnapshotFloater->postSave();
+ LLFloaterSnapshot::getInstance()->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
+}
+
+void LLPanelSnapshotLocal::onLocalCanceled()
+{
+ cancel();
+ LLFloaterSnapshot::getInstance()->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "local")));
}
+
LLSnapshotModel::ESnapshotType LLPanelSnapshotLocal::getSnapshotType()
{
return LLSnapshotModel::SNAPSHOT_LOCAL;
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index ee8b2d79c0..d0cff1464b 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -70,6 +70,7 @@ S32 BORDER_WIDTH = 6;
const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
std::set<LLSnapshotLivePreview*> LLSnapshotLivePreview::sList;
+LLPointer<LLImageFormatted> LLSnapshotLivePreview::sSaveLocalImage = NULL;
LLSnapshotLivePreview::LLSnapshotLivePreview (const LLSnapshotLivePreview::Params& p)
: LLView(p),
@@ -131,6 +132,7 @@ LLSnapshotLivePreview::~LLSnapshotLivePreview()
// gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
sList.erase(this);
+ sSaveLocalImage = NULL;
}
void LLSnapshotLivePreview::setMaxImageSize(S32 size)
@@ -1065,53 +1067,19 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
mDataSize = 0;
}
-BOOL LLSnapshotLivePreview::saveLocal()
+void LLSnapshotLivePreview::saveLocal(const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
// Update mFormattedImage if necessary
getFormattedImage();
// Save the formatted image
- BOOL success = saveLocal(mFormattedImage);
-
- if(success)
- {
- gViewerWindow->playSnapshotAnimAndSound();
- }
- return success;
+ saveLocal(mFormattedImage, success_cb, failure_cb);
}
//Check if failed due to insufficient memory
-BOOL LLSnapshotLivePreview::saveLocal(LLPointer<LLImageFormatted> mFormattedImage)
+void LLSnapshotLivePreview::saveLocal(LLPointer<LLImageFormatted> image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
- BOOL insufficient_memory;
- BOOL success = gViewerWindow->saveImageNumbered(mFormattedImage, FALSE, insufficient_memory);
+ sSaveLocalImage = image;
- if (insufficient_memory)
- {
- std::string lastSnapshotDir = LLViewerWindow::getLastSnapshotDir();
-
-#ifdef LL_WINDOWS
- boost::filesystem::path b_path(utf8str_to_utf16str(lastSnapshotDir));
-#else
- boost::filesystem::path b_path(lastSnapshotDir);
-#endif
- boost::filesystem::space_info b_space = boost::filesystem::space(b_path);
- if (b_space.free < mFormattedImage->getDataSize())
- {
- LLSD args;
- args["PATH"] = lastSnapshotDir;
-
- std::string needM_bytes_string;
- LLResMgr::getInstance()->getIntegerString(needM_bytes_string, (mFormattedImage->getDataSize()) >> 10);
- args["NEED_MEMORY"] = needM_bytes_string;
-
- std::string freeM_bytes_string;
- LLResMgr::getInstance()->getIntegerString(freeM_bytes_string, (b_space.free) >> 10);
- args["FREE_MEMORY"] = freeM_bytes_string;
-
- LLNotificationsUtil::add("SnapshotToComputerFailed", args);
- return false;
- }
- }
- return success;
+ gViewerWindow->saveImageNumbered(sSaveLocalImage, FALSE, success_cb, failure_cb);
}
diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h
index 4ea8d25a5a..683cd016d8 100644
--- a/indra/newview/llsnapshotlivepreview.h
+++ b/indra/newview/llsnapshotlivepreview.h
@@ -40,8 +40,9 @@ class LLSnapshotLivePreview : public LLView
{
LOG_CLASS(LLSnapshotLivePreview);
public:
+ typedef boost::signals2::signal<void(void)> snapshot_saved_signal_t;
- static BOOL saveLocal(LLPointer<LLImageFormatted>);
+ static void saveLocal(LLPointer<LLImageFormatted> image, const snapshot_saved_signal_t::slot_type& success_cb = snapshot_saved_signal_t(), const snapshot_saved_signal_t::slot_type& failure_cb = snapshot_saved_signal_t());
struct Params : public LLInitParam::Block<Params, LLView::Params>
{
Params()
@@ -101,7 +102,7 @@ public:
std::string getFilter() const { return mFilterName; }
void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
void saveTexture(BOOL outfit_snapshot = FALSE, std::string name = "");
- BOOL saveLocal();
+ void saveLocal(const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
LLPointer<LLImageFormatted> getFormattedImage();
LLPointer<LLImageRaw> getEncodedImage();
@@ -170,7 +171,9 @@ private:
LLQuaternion mCameraRot;
BOOL mSnapshotActive;
LLSnapshotModel::ESnapshotLayerType mSnapshotBufferType;
- std::string mFilterName;
+ std::string mFilterName;
+
+ static LLPointer<LLImageFormatted> sSaveLocalImage;
public:
static std::set<LLSnapshotLivePreview*> sList;
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index dc05d98228..cf1c442ce9 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -203,38 +203,55 @@ void LLFilePickerThread::clearDead()
}
}
-LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple)
+LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb)
: LLFilePickerThread(filter, get_multiple),
mLoadFilter(filter),
mSaveFilter(LLFilePicker::FFSAVE_ALL),
- mFilePickedSignal(NULL)
+ mFilePickedSignal(NULL),
+ mFailureSignal(NULL)
{
mFilePickedSignal = new file_picked_signal_t();
mFilePickedSignal->connect(cb);
+
+ mFailureSignal = new file_picked_signal_t();
+ mFailureSignal->connect(failure_cb);
}
-LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name)
+LLFilePickerReplyThread::LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb)
: LLFilePickerThread(filter, proposed_name),
mLoadFilter(LLFilePicker::FFLOAD_ALL),
mSaveFilter(filter),
- mFilePickedSignal(NULL)
+ mFilePickedSignal(NULL),
+ mFailureSignal(NULL)
{
mFilePickedSignal = new file_picked_signal_t();
mFilePickedSignal->connect(cb);
+
+ mFailureSignal = new file_picked_signal_t();
+ mFailureSignal->connect(failure_cb);
}
LLFilePickerReplyThread::~LLFilePickerReplyThread()
{
delete mFilePickedSignal;
+ delete mFailureSignal;
}
void LLFilePickerReplyThread::notify(const std::vector<std::string>& filenames)
{
- if (filenames.empty()) return;
-
- if (mFilePickedSignal)
+ if (filenames.empty())
+ {
+ if (mFailureSignal)
+ {
+ (*mFailureSignal)(filenames, mLoadFilter, mSaveFilter);
+ }
+ }
+ else
{
- (*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter);
+ if (mFilePickedSignal)
+ {
+ (*mFilePickedSignal)(filenames, mLoadFilter, mSaveFilter);
+ }
}
}
@@ -592,7 +609,6 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
gSavedSettings.getBOOL("RenderUIInSnapshot"),
FALSE))
{
- gViewerWindow->playSnapshotAnimAndSound();
LLPointer<LLImageFormatted> formatted;
LLSnapshotModel::ESnapshotFormat fmt = (LLSnapshotModel::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
switch (fmt)
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index 15bbdd1e2d..35f86f606b 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -113,8 +113,8 @@ 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(const file_picked_signal_t::slot_type& cb, LLFilePicker::ELoadFilter filter, bool get_multiple, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
+ LLFilePickerReplyThread(const file_picked_signal_t::slot_type& cb, LLFilePicker::ESaveFilter filter, const std::string &proposed_name, const file_picked_signal_t::slot_type& failure_cb = file_picked_signal_t());
~LLFilePickerReplyThread();
virtual void notify(const std::vector<std::string>& filenames);
@@ -123,6 +123,7 @@ private:
LLFilePicker::ELoadFilter mLoadFilter;
LLFilePicker::ESaveFilter mSaveFilter;
file_picked_signal_t* mFilePickedSignal;
+ file_picked_signal_t* mFailureSignal;
};
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index f394d6913f..846b902260 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -193,6 +193,7 @@
#include "llviewerdisplay.h"
#include "llspatialpartition.h"
#include "llviewerjoystick.h"
+#include "llviewermenufile.h" // LLFilePickerReplyThread
#include "llviewernetwork.h"
#include "llpostprocess.h"
#include "llfloaterimnearbychat.h"
@@ -4365,77 +4366,101 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d
}
// Saves an image to the harddrive as "SnapshotX" where X >= 1.
-BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picker, BOOL& insufficient_memory)
+void LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picker, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
{
- insufficient_memory = FALSE;
-
if (!image)
{
LL_WARNS() << "No image to save" << LL_ENDL;
- return FALSE;
+ return;
}
-
- LLFilePicker::ESaveFilter pick_type;
std::string extension("." + image->getExtension());
- if (extension == ".j2c")
- pick_type = LLFilePicker::FFSAVE_J2C;
- else if (extension == ".bmp")
- pick_type = LLFilePicker::FFSAVE_BMP;
- else if (extension == ".jpg")
- pick_type = LLFilePicker::FFSAVE_JPEG;
- else if (extension == ".png")
- pick_type = LLFilePicker::FFSAVE_PNG;
- else if (extension == ".tga")
- pick_type = LLFilePicker::FFSAVE_TGA;
- else
- pick_type = LLFilePicker::FFSAVE_ALL; // ???
-
- BOOL is_snapshot_name_loc_set = isSnapshotLocSet();
-
+ LLImageFormatted* formatted_image = image;
// Get a base file location if needed.
if (force_picker || !isSnapshotLocSet())
{
- std::string proposed_name( sSnapshotBaseName );
+ std::string proposed_name(sSnapshotBaseName);
// getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in.
+ LLFilePicker::ESaveFilter pick_type;
+
+ if (extension == ".j2c")
+ pick_type = LLFilePicker::FFSAVE_J2C;
+ else if (extension == ".bmp")
+ pick_type = LLFilePicker::FFSAVE_BMP;
+ else if (extension == ".jpg")
+ pick_type = LLFilePicker::FFSAVE_JPEG;
+ else if (extension == ".png")
+ pick_type = LLFilePicker::FFSAVE_PNG;
+ else if (extension == ".tga")
+ pick_type = LLFilePicker::FFSAVE_TGA;
+ else
+ pick_type = LLFilePicker::FFSAVE_ALL;
- // pick a directory in which to save
- LLFilePicker& picker = LLFilePicker::instance();
- if (!picker.getSaveFile(pick_type, proposed_name))
- {
- // Clicked cancel
- return FALSE;
- }
+ (new LLFilePickerReplyThread(boost::bind(&LLViewerWindow::onDirectorySelected, this, _1, formatted_image, success_cb, failure_cb), pick_type, proposed_name,
+ boost::bind(&LLViewerWindow::onSelectionFailure, this, failure_cb)))->getFile();
+ }
+ else
+ {
+ saveImageLocal(formatted_image, success_cb, failure_cb);
+ }
+}
- // Copy the directory + file name
- std::string filepath = picker.getFirstFile();
+void LLViewerWindow::onDirectorySelected(const std::vector<std::string>& filenames, LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
+{
+ // Copy the directory + file name
+ std::string filepath = filenames[0];
- gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true));
- gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath));
- }
+ gSavedPerAccountSettings.setString("SnapshotBaseName", gDirUtilp->getBaseFileName(filepath, true));
+ gSavedPerAccountSettings.setString("SnapshotBaseDir", gDirUtilp->getDirName(filepath));
+ saveImageLocal(image, success_cb, failure_cb);
+}
- std::string snapshot_dir = sSnapshotDir;
- if(snapshot_dir.empty())
+void LLViewerWindow::onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb)
+{
+ failure_cb();
+}
+
+
+void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb)
+{
+ std::string lastSnapshotDir = LLViewerWindow::getLastSnapshotDir();
+ if (lastSnapshotDir.empty())
{
- return FALSE;
+ failure_cb();
+ return;
}
// Check if there is enough free space to save snapshot
#ifdef LL_WINDOWS
- boost::filesystem::space_info b_space = boost::filesystem::space(utf8str_to_utf16str(snapshot_dir));
+ boost::filesystem::path b_path(utf8str_to_utf16str(lastSnapshotDir));
#else
- boost::filesystem::space_info b_space = boost::filesystem::space(snapshot_dir);
+ boost::filesystem::path b_path(lastSnapshotDir);
#endif
+ boost::filesystem::space_info b_space = boost::filesystem::space(b_path);
if (b_space.free < image->getDataSize())
{
- insufficient_memory = TRUE;
- return FALSE;
+ LLSD args;
+ args["PATH"] = lastSnapshotDir;
+
+ std::string needM_bytes_string;
+ LLResMgr::getInstance()->getIntegerString(needM_bytes_string, (image->getDataSize()) >> 10);
+ args["NEED_MEMORY"] = needM_bytes_string;
+
+ std::string freeM_bytes_string;
+ LLResMgr::getInstance()->getIntegerString(freeM_bytes_string, (b_space.free) >> 10);
+ args["FREE_MEMORY"] = freeM_bytes_string;
+
+ LLNotificationsUtil::add("SnapshotToComputerFailed", args);
+
+ failure_cb();
}
+
// Look for an unused file name
+ BOOL is_snapshot_name_loc_set = isSnapshotLocSet();
std::string filepath;
S32 i = 1;
S32 err = 0;
-
+ std::string extension("." + image->getExtension());
do
{
filepath = sSnapshotDir;
@@ -4457,7 +4482,15 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, BOOL force_picke
&& is_snapshot_name_loc_set); // Or stop if we are rewriting.
LL_INFOS() << "Saving snapshot to " << filepath << LL_ENDL;
- return image->save(filepath);
+ if (image->save(filepath))
+ {
+ playSnapshotAnimAndSound();
+ success_cb();
+ }
+ else
+ {
+ failure_cb();
+ }
}
void LLViewerWindow::resetSnapshotLoc()
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index c01921641c..d8d420e6be 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -352,7 +352,13 @@ public:
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, LLSnapshotModel::ESnapshotLayerType type);
BOOL isSnapshotLocSet() const;
void resetSnapshotLoc() const;
- BOOL saveImageNumbered(LLImageFormatted *image, BOOL force_picker, BOOL& insufficient_memory);
+
+ typedef boost::signals2::signal<void(void)> snapshot_saved_signal_t;
+
+ void saveImageNumbered(LLImageFormatted *image, BOOL force_picker, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
+ void onDirectorySelected(const std::vector<std::string>& filenames, LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
+ void saveImageLocal(LLImageFormatted *image, const snapshot_saved_signal_t::slot_type& success_cb, const snapshot_saved_signal_t::slot_type& failure_cb);
+ void onSelectionFailure(const snapshot_saved_signal_t::slot_type& failure_cb);
// Reset the directory where snapshots are saved.
// Client will open directory picker on next snapshot save.