diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index df16124233..89980f125a 100755 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -1551,7 +1551,10 @@ void LLFloaterSnapshot::saveTexture() } // static -BOOL LLFloaterSnapshot::saveLocal() +// Threaded filepickers +//BOOL LLFloaterSnapshot::saveLocal() +void LLFloaterSnapshot::saveLocal(boost::function callback) +// { LL_DEBUGS() << "saveLocal" << LL_ENDL; // FIXME: duplicated code @@ -1559,16 +1562,33 @@ BOOL LLFloaterSnapshot::saveLocal() if (!instance) { llassert(instance != NULL); - return FALSE; + // Threaded filepickers + //return FALSE; + if (callback) + { + callback(false); + } + return; + // } LLSnapshotLivePreview* previewp = Impl::getPreviewView(instance); if (!previewp) { llassert(previewp != NULL); - return FALSE; + // Threaded filepickers + //return FALSE; + if (callback) + { + callback(false); + } + return; + // } - return previewp->saveLocal(); + // Threaded filepickers + //return previewp->saveLocal(); + previewp->saveLocal(callback); + // } // static diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h index c422178525..e9f3bb5509 100755 --- a/indra/newview/llfloatersnapshot.h +++ b/indra/newview/llfloatersnapshot.h @@ -58,7 +58,10 @@ public: static LLFloaterSnapshot* getInstance(); static LLFloaterSnapshot* findInstance(); static void saveTexture(); - static BOOL saveLocal(); + // Threaded filepickers + //static BOOL saveLocal(); + static void saveLocal(boost::function callback); + // static void postSave(); static void postPanelSwitch(); static LLPointer getImageData(); diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp index 94226280bc..395326559d 100755 --- a/indra/newview/llpanelsnapshotlocal.cpp +++ b/indra/newview/llpanelsnapshotlocal.cpp @@ -61,6 +61,9 @@ private: /*virtual*/ LLFloaterSnapshot::ESnapshotFormat getImageFormat() const; /*virtual*/ void updateControls(const LLSD& info); + // 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(); - // 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 - { - // Notify user if we could not save file - LLNotificationsUtil::add("CannotSaveSnapshot"); - floater->notify(LLSD().with("set-ready", true)); - // Don't return to target selection after taking a snapshot - //cancel(); - } + // 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)); + // } // Store settings at logout @@ -206,3 +206,21 @@ LLPanelSnapshotLocal::~LLPanelSnapshotLocal() gSavedSettings.setS32("LastSnapshotToDiskHeight", getTypedPreviewHeight()); } // + +// 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)); + } +} +// diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp index 185c73cc16..90c6611e65 100644 --- a/indra/newview/llsnapshotlivepreview.cpp +++ b/indra/newview/llsnapshotlivepreview.cpp @@ -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); +// 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 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 callback) +{ if(success) { gViewerWindow->playSnapshotAnimAndSound(); } - return success; -} + if (callback) + { + callback(success); + } +} +// diff --git a/indra/newview/llsnapshotlivepreview.h b/indra/newview/llsnapshotlivepreview.h index f16d22f415..2b8b3955f9 100644 --- a/indra/newview/llsnapshotlivepreview.h +++ b/indra/newview/llsnapshotlivepreview.h @@ -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(); + // Threaded filepickers + //BOOL saveLocal(); + void saveLocal(boost::function callback); + void saveLocalCallback(bool success, boost::function callback); + // LLPointer getFormattedImage(); LLPointer getEncodedImage(); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 0124949063..39d16c2451 100755 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -711,6 +711,18 @@ class LLFileCloseAllWindows : public view_listener_t } }; +// Threaded filepickers +LLPointer sFormattedSnapshotImage = NULL; +void take_snapshot_to_disk_callback(bool success) +{ + sFormattedSnapshotImage = NULL; + if (success) + { + gViewerWindow->playSnapshotAnimAndSound(); + } +} +// + 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 formatted; + // Threaded filepickers + //gViewerWindow->playSnapshotAnimAndSound(); + //LLPointer 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)); + // } return true; } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 6d48ec1712..dd55e5ae1e 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -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; } +// Threaded filepickers +void do_save_image(LLImageFormatted* image, const std::string& snapshot_dir, const std::string& base_name, const std::string& extension, boost::function 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 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); + } +} +// + // Saves an image to the harddrive as "SnapshotX" where X >= 1. -BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, bool force_picker) +// Threaded filepickers +//BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, bool force_picker) +void LLViewerWindow::saveImageNumbered(LLImageFormatted *image, bool force_picker, boost::function callback) +// { if (!image) { LL_WARNS() << "No image to save" << LL_ENDL; - return FALSE; + // Threaded filepickers + //return FALSE; + if (callback) + { + callback(false); + return; + } + // } LLFilePicker::ESaveFilter pick_type; @@ -4727,57 +4794,62 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image, bool force_picke else pick_type = LLFilePicker::FFSAVE_ALL; // ??? + // 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; - // 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)); - } - // - return image->save(filepath); + do_save_image(image, LLViewerWindow::sSnapshotDir, LLViewerWindow::sSnapshotBaseName, extension, callback); + // } void LLViewerWindow::resetSnapshotLoc() diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 899969091a..c2671d198e 100755 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -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); + // Threaded filepickers + //BOOL saveImageNumbered(LLImageFormatted *image, bool force_picker = false); + void saveImageNumbered(LLImageFormatted *image, bool force_picker = false, boost::function callback = NULL); + void saveImageCallback(const std::string& filename, LLImageFormatted* image, const std::string& extension, boost::function callback); + // // Reset the directory where snapshots are saved. // Client will open directory picker on next snapshot save.