Threaded filepickers for snapshot to disk

meow-7.2.2
Ansariel 2016-04-07 16:57:55 +02:00
parent 42acac2fe5
commit f3d970a5a7
8 changed files with 265 additions and 87 deletions

View File

@ -1551,7 +1551,10 @@ void LLFloaterSnapshot::saveTexture()
}
// static
BOOL LLFloaterSnapshot::saveLocal()
// <FS:Ansariel> Threaded filepickers
//BOOL LLFloaterSnapshot::saveLocal()
void LLFloaterSnapshot::saveLocal(boost::function<void(bool)> callback)
// </FS:Ansariel>
{
LL_DEBUGS() << "saveLocal" << LL_ENDL;
// FIXME: duplicated code
@ -1559,16 +1562,33 @@ BOOL LLFloaterSnapshot::saveLocal()
if (!instance)
{
llassert(instance != NULL);
return FALSE;
// <FS:Ansariel> Threaded filepickers
//return FALSE;
if (callback)
{
callback(false);
}
return;
// </FS:Ansariel>
}
LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance);
if (!previewp)
{
llassert(previewp != NULL);
return FALSE;
// <FS:Ansariel> Threaded filepickers
//return FALSE;
if (callback)
{
callback(false);
}
return;
// </FS:Ansariel>
}
return previewp->saveLocal();
// <FS:Ansariel> Threaded filepickers
//return previewp->saveLocal();
previewp->saveLocal(callback);
// </FS:Ansariel>
}
// static

View File

@ -58,7 +58,10 @@ public:
static LLFloaterSnapshot* getInstance();
static LLFloaterSnapshot* findInstance();
static void saveTexture();
static BOOL saveLocal();
// <FS:Ansariel> Threaded filepickers
//static BOOL saveLocal();
static void saveLocal(boost::function<void(bool)> callback);
// </FS:Ansariel>
static void postSave();
static void postPanelSwitch();
static LLPointer<LLImageFormatted> getImageData();

View File

@ -61,6 +61,9 @@ private:
/*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const;
/*virtual*/ void updateControls(const LLSD& info);
// <FS:Ansariel> Threaded filepickers
void saveLocalCallback(bool success);
S32 mLocalFormat;
void onFormatComboCommit(LLUICtrl* ctrl);
@ -180,22 +183,19 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl)
LLFloaterSnapshot* floater = LLFloaterSnapshot::getInstance();
floater->notify(LLSD().with("set-working", true));
BOOL saved = LLFloaterSnapshot::saveLocal();
if (saved)
{
LLFloaterSnapshot::postSave();
// <FS:Ansariel> Don't return to target selection after taking a snapshot
//goBack();
floater->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
}
else
{
// <FS:Ansariel> Notify user if we could not save file
LLNotificationsUtil::add("CannotSaveSnapshot");
floater->notify(LLSD().with("set-ready", true));
// <FS:Ansariel> Don't return to target selection after taking a snapshot
//cancel();
}
// <FS:Ansariel> Threaded filepickers
//BOOL saved = LLFloaterSnapshot::saveLocal();
//if (saved)
//{
// LLFloaterSnapshot::postSave();
// floater->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
//}
//else
//{
// cancel();
//}
LLFloaterSnapshot::saveLocal(boost::bind(&LLPanelSnapshotLocal::saveLocalCallback, this, _1));
// </FS:Ansariel>
}
// <FS:Ansariel> Store settings at logout
@ -206,3 +206,21 @@ LLPanelSnapshotLocal::~LLPanelSnapshotLocal()
gSavedSettings.setS32("LastSnapshotToDiskHeight", getTypedPreviewHeight());
}
// </FS:Ansariel>
// <FS:Ansariel> Threaded filepickers
void LLPanelSnapshotLocal::saveLocalCallback(bool success)
{
LLFloaterSnapshot* floater = LLFloaterSnapshot::getInstance();
if (success)
{
LLFloaterSnapshot::postSave();
floater->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
}
else
{
LLNotificationsUtil::add("CannotSaveSnapshot");
floater->notify(LLSD().with("set-ready", true));
}
}
// </FS:Ansariel>

View File

@ -1095,18 +1095,41 @@ void LLSnapshotLivePreview::saveTexture()
mDataSize = 0;
}
BOOL LLSnapshotLivePreview::saveLocal()
{
// Update mFormattedImage if necessary
getFormattedImage();
// Save the formatted image
BOOL success = gViewerWindow->saveImageNumbered(mFormattedImage);
// <FS:Ansariel> Threaded filepickers
//BOOL LLSnapshotLivePreview::saveLocal()
//{
// // Update mFormattedImage if necessary
// getFormattedImage();
//
// // Save the formatted image
// BOOL success = gViewerWindow->saveImageNumbered(mFormattedImage);
//
// if(success)
// {
// gViewerWindow->playSnapshotAnimAndSound();
// }
// return success;
//}
void LLSnapshotLivePreview::saveLocal(boost::function<void(bool)> callback)
{
// Update mFormattedImage if necessary
getFormattedImage();
// Save the formatted image
gViewerWindow->saveImageNumbered(mFormattedImage, false, boost::bind(&LLSnapshotLivePreview::saveLocalCallback, this, _1, callback));
}
void LLSnapshotLivePreview::saveLocalCallback(bool success, boost::function<void(bool)> callback)
{
if(success)
{
gViewerWindow->playSnapshotAnimAndSound();
}
return success;
}
if (callback)
{
callback(success);
}
}
// </FS:Ansariel>

View File

@ -112,7 +112,11 @@ public:
std::string getFilter() const { return mFilterName; }
void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
void saveTexture();
BOOL saveLocal();
// <FS:Ansariel> Threaded filepickers
//BOOL saveLocal();
void saveLocal(boost::function<void(bool)> callback);
void saveLocalCallback(bool success, boost::function<void(bool)> callback);
// </FS:Ansariel>
LLPointer<LLImageFormatted> getFormattedImage();
LLPointer<LLImageRaw> getEncodedImage();

View File

@ -711,6 +711,18 @@ class LLFileCloseAllWindows : public view_listener_t
}
};
// <FS:Ansariel> Threaded filepickers
LLPointer<LLImageFormatted> sFormattedSnapshotImage = NULL;
void take_snapshot_to_disk_callback(bool success)
{
sFormattedSnapshotImage = NULL;
if (success)
{
gViewerWindow->playSnapshotAnimAndSound();
}
}
// </FS:Ansariel>
class LLFileTakeSnapshotToDisk : public view_listener_t
{
bool handleEvent(const LLSD& userdata)
@ -734,27 +746,49 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
gSavedSettings.getBOOL("RenderUIInSnapshot"),
FALSE))
{
gViewerWindow->playSnapshotAnimAndSound();
LLPointer<LLImageFormatted> formatted;
// <FS:Ansariel> Threaded filepickers
//gViewerWindow->playSnapshotAnimAndSound();
//LLPointer<LLImageFormatted> formatted;
//LLFloaterSnapshot::ESnapshotFormat fmt = (LLFloaterSnapshot::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
//switch (fmt)
//{
//case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
// formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality"));
// break;
//default:
// LL_WARNS() << "Unknown local snapshot format: " << fmt << LL_ENDL;
//case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
// formatted = new LLImagePNG;
// break;
//case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
// formatted = new LLImageBMP;
// break;
//}
//formatted->enableOverSize() ;
//formatted->encode(raw, 0);
//formatted->disableOverSize() ;
//gViewerWindow->saveImageNumbered(formatted);
LLFloaterSnapshot::ESnapshotFormat fmt = (LLFloaterSnapshot::ESnapshotFormat) gSavedSettings.getS32("SnapshotFormat");
switch (fmt)
{
case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality"));
sFormattedSnapshotImage = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality"));
break;
default:
LL_WARNS() << "Unknown local snapshot format: " << fmt << LL_ENDL;
case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
formatted = new LLImagePNG;
sFormattedSnapshotImage = new LLImagePNG;
break;
case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
formatted = new LLImageBMP;
sFormattedSnapshotImage = new LLImageBMP;
break;
}
formatted->enableOverSize() ;
formatted->encode(raw, 0);
formatted->disableOverSize() ;
gViewerWindow->saveImageNumbered(formatted);
sFormattedSnapshotImage->enableOverSize() ;
sFormattedSnapshotImage->encode(raw, 0);
sFormattedSnapshotImage->disableOverSize() ;
gViewerWindow->saveImageNumbered(sFormattedSnapshotImage, false, boost::bind(&take_snapshot_to_disk_callback, _1));
// </FS:Ansariel>
}
return true;
}

View File

@ -217,6 +217,7 @@
#include "llviewerwindowlistener.h"
#include "llpaneltopinfobar.h"
#include "llimview.h"
#include "llviewermenufile.h"
// [RLVa:KB] - Checked: 2010-03-31 (RLVa-1.2.0c)
#include "rlvhandler.h"
@ -4703,13 +4704,79 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d
return FALSE;
}
// <FS:Ansariel> Threaded filepickers
void do_save_image(LLImageFormatted* image, const std::string& snapshot_dir, const std::string& base_name, const std::string& extension, boost::function<void(bool)> callback)
{
// Look for an unused file name
std::string filepath;
S32 i = 1;
S32 err = 0;
do
{
filepath = snapshot_dir;
filepath += gDirUtilp->getDirDelimiter();
filepath += base_name;
filepath += llformat("_%.3d",i);
filepath += extension;
llstat stat_info;
err = LLFile::stat( filepath, &stat_info );
i++;
}
while( -1 != err ); // search until the file is not found (i.e., stat() gives an error).
LL_INFOS() << "Saving snapshot to " << filepath << LL_ENDL;
if (gSavedSettings.getBOOL("FSLogSnapshotsToLocal"))
{
LLStringUtil::format_map_t args;
args["FILENAME"] = filepath;
report_to_nearby_chat(LLTrans::getString("SnapshotSavedToDisk", args));
}
bool success = image->save(filepath);
if (callback)
{
callback(success);
}
}
void LLViewerWindow::saveImageCallback(const std::string& filename, LLImageFormatted* image, const std::string& extension, boost::function<void(bool)> callback)
{
if (!filename.empty())
{
LLViewerWindow::sSnapshotBaseName = gDirUtilp->getBaseFileName(filename, true);
LLViewerWindow::sSnapshotDir = gDirUtilp->getDirName(filename);
do_save_image(image, LLViewerWindow::sSnapshotDir, LLViewerWindow::sSnapshotBaseName, extension, callback);
return;
}
if (callback)
{
callback(false);
}
}
// </FS:Ansariel>
// Saves an image to the harddrive as "SnapshotX" where X >= 1.
BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, bool force_picker)
// <FS:Ansariel> Threaded filepickers
//BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, bool force_picker)
void LLViewerWindow::saveImageNumbered(LLImageFormatted *image, bool force_picker, boost::function<void(bool)> callback)
// </FS:Ansariel>
{
if (!image)
{
LL_WARNS() << "No image to save" << LL_ENDL;
return FALSE;
// <FS:Ansariel> Threaded filepickers
//return FALSE;
if (callback)
{
callback(false);
return;
}
// </FS:Ansariel>
}
LLFilePicker::ESaveFilter pick_type;
@ -4727,57 +4794,62 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, bool force_picke
else
pick_type = LLFilePicker::FFSAVE_ALL; // ???
// <FS:Ansariel> Threaded filepickers
//// Get a base file location if needed.
//if (force_picker || !isSnapshotLocSet())
//{
// std::string proposed_name( sSnapshotBaseName );
// // getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in.
// // pick a directory in which to save
// LLFilePicker& picker = LLFilePicker::instance();
// if (!picker.getSaveFile(pick_type, proposed_name))
// {
// // Clicked cancel
// return FALSE;
// }
// // Copy the directory + file name
// std::string filepath = picker.getFirstFile();
// LLViewerWindow::sSnapshotBaseName = gDirUtilp->getBaseFileName(filepath, true);
// LLViewerWindow::sSnapshotDir = gDirUtilp->getDirName(filepath);
//}
//// Look for an unused file name
//std::string filepath;
//S32 i = 1;
//S32 err = 0;
//do
//{
// filepath = sSnapshotDir;
// filepath += gDirUtilp->getDirDelimiter();
// filepath += sSnapshotBaseName;
// filepath += llformat("_%.3d",i);
// filepath += extension;
// llstat stat_info;
// err = LLFile::stat( filepath, &stat_info );
// i++;
//}
//while( -1 != err ); // search until the file is not found (i.e., stat() gives an error).
//LL_INFOS() << "Saving snapshot to " << filepath << LL_ENDL;
//return image->save(filepath);
// Get a base file location if needed.
if (force_picker || !isSnapshotLocSet())
{
std::string proposed_name( sSnapshotBaseName );
// getSaveFile will append an appropriate extension to the proposed name, based on the ESaveFilter constant passed in.
// pick a directory in which to save
LLFilePicker& picker = LLFilePicker::instance();
if (!picker.getSaveFile(pick_type, proposed_name))
{
// Clicked cancel
return FALSE;
}
// Copy the directory + file name
std::string filepath = picker.getFirstFile();
LLViewerWindow::sSnapshotBaseName = gDirUtilp->getBaseFileName(filepath, true);
LLViewerWindow::sSnapshotDir = gDirUtilp->getDirName(filepath);
(new LLGenericSaveFilePicker(pick_type, proposed_name, boost::bind(&LLViewerWindow::saveImageCallback, this, _1, image, extension, callback)))->getFile();
return;
}
// Look for an unused file name
std::string filepath;
S32 i = 1;
S32 err = 0;
do
{
filepath = sSnapshotDir;
filepath += gDirUtilp->getDirDelimiter();
filepath += sSnapshotBaseName;
filepath += llformat("_%.3d",i);
filepath += extension;
llstat stat_info;
err = LLFile::stat( filepath, &stat_info );
i++;
}
while( -1 != err ); // search until the file is not found (i.e., stat() gives an error).
LL_INFOS() << "Saving snapshot to " << filepath << LL_ENDL;
//<FS:Kadah> Log snapshot filename to local chat history
if (gSavedSettings.getBOOL("FSLogSnapshotsToLocal"))
{
LLStringUtil::format_map_t args;
args["FILENAME"] = filepath;
report_to_nearby_chat(LLTrans::getString("SnapshotSavedToDisk", args));
}
//</FS:Kadah>
return image->save(filepath);
do_save_image(image, LLViewerWindow::sSnapshotDir, LLViewerWindow::sSnapshotBaseName, extension, callback);
// </FS:Ansariel>
}
void LLViewerWindow::resetSnapshotLoc()

View File

@ -355,7 +355,11 @@ public:
BOOL thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ;
BOOL isSnapshotLocSet() const { return ! sSnapshotDir.empty(); }
void resetSnapshotLoc() const { sSnapshotDir.clear(); }
BOOL saveImageNumbered(LLImageFormatted *image, bool force_picker = false);
// <FS:Ansariel> Threaded filepickers
//BOOL saveImageNumbered(LLImageFormatted *image, bool force_picker = false);
void saveImageNumbered(LLImageFormatted *image, bool force_picker = false, boost::function<void(bool)> callback = NULL);
void saveImageCallback(const std::string& filename, LLImageFormatted* image, const std::string& extension, boost::function<void(bool)> callback);
// </FS:Ansariel>
// Reset the directory where snapshots are saved.
// Client will open directory picker on next snapshot save.