diff options
| -rw-r--r-- | indra/llfilesystem/lldir.cpp | 47 | ||||
| -rw-r--r-- | indra/llfilesystem/lldir.h | 3 | ||||
| -rw-r--r-- | indra/newview/llpanelgenerictip.cpp | 8 | ||||
| -rw-r--r-- | indra/newview/llviewerwindow.cpp | 23 | ||||
| -rw-r--r-- | indra/newview/llviewerwindow.h | 1 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 8 |
6 files changed, 90 insertions, 0 deletions
diff --git a/indra/llfilesystem/lldir.cpp b/indra/llfilesystem/lldir.cpp index 190539cea5..7d547ca4be 100644 --- a/indra/llfilesystem/lldir.cpp +++ b/indra/llfilesystem/lldir.cpp @@ -44,6 +44,7 @@ #include "stringize.h" #include "llstring.h" #include <boost/filesystem.hpp> +#include "llprocess.h" #include <boost/bind.hpp> #include <algorithm> @@ -1100,6 +1101,52 @@ LLDir::SepOff LLDir::needSep(const std::string& path, const std::string& name) c return SepOff(false, 0); } +void LLDir::openDir(const std::string& filepath) +{ + if (filepath.empty()) + { + LL_WARNS() << "Cannot open file browser: filepath is empty" << LL_ENDL; + return; + } + + // Extract directory path from full filepath + std::string dir_path = getDirName(filepath); + + LLProcess::Params params; + +#if LL_WINDOWS + // Windows: Use explorer.exe with /select flag to highlight the file + std::string system_root = LLStringUtil::getenv("SystemRoot", "C:\\Windows"); + params.executable = system_root + "\\explorer.exe"; + params.args.add("/select,"); + params.args.add(filepath); +#elif LL_DARWIN + // macOS: Use 'open' command with -R flag to reveal in Finder + params.executable = "/usr/bin/open"; + params.args.add("-R"); + params.args.add(filepath); +#elif LL_LINUX + // Linux: Use xdg-open to open the directory + // Note: Most file managers don't support file selection, so we open the directory + params.executable = "/usr/bin/xdg-open"; + params.args.add(dir_path); +#else + LL_WARNS() << "Platform not supported for file browser opening" << LL_ENDL; + return; +#endif + + params.autokill = false; // Don't kill the file browser when viewer exits + + if (!LLProcess::create(params)) + { + LL_WARNS() << "Failed to open file browser for: " << filepath << LL_ENDL; + } + else + { + LL_INFOS() << "Opened file browser for: " << filepath << LL_ENDL; + } +} + void dir_exists_or_crash(const std::string &dir_name) { #if LL_WINDOWS diff --git a/indra/llfilesystem/lldir.h b/indra/llfilesystem/lldir.h index b0d2b6aada..3c8e2e2da6 100644 --- a/indra/llfilesystem/lldir.h +++ b/indra/llfilesystem/lldir.h @@ -194,6 +194,9 @@ class LLDir virtual void dumpCurrentDirectories(LLError::ELevel level = LLError::LEVEL_DEBUG); + // Open the system file browser to reveal a file or directory + void openDir(const std::string& filepath); + // Utility routine std::string buildSLOSCacheDir() const; diff --git a/indra/newview/llpanelgenerictip.cpp b/indra/newview/llpanelgenerictip.cpp index bc2b28269f..1b5228713e 100644 --- a/indra/newview/llpanelgenerictip.cpp +++ b/indra/newview/llpanelgenerictip.cpp @@ -43,5 +43,13 @@ LLPanelGenericTip::LLPanelGenericTip( S32 max_line_count = gSavedSettings.getS32("TipToastMessageLineCount"); snapToMessageHeight(getChild<LLTextBox> ("message"), max_line_count); + + // Check if notification should respond to mouse clicks + if (notification->getPayload().has("respond_on_mousedown") + && notification->getPayload()["respond_on_mousedown"]) + { + setMouseDownCallback(boost::bind(&LLNotification::respond, + notification, notification->getResponseTemplate())); + } } diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 725178c1b9..8695b96952 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4918,6 +4918,19 @@ void LLViewerWindow::saveImageLocal(LLImageFormatted *image, const snapshot_save if (image->save(filepath)) { playSnapshotAnimAndSound(); + + // Show clickable notification with filepath + LLSD args; + args["FILEPATH"] = filepath; + + LLSD payload; + payload["filepath"] = filepath; + + LLNotificationsUtil::add("SnapshotSavedToComputer", + args, + payload.with("respond_on_mousedown", true), + boost::bind(&LLViewerWindow::onSnapshotNotificationClick, _1, _2)); + success_cb(); } else @@ -4932,6 +4945,16 @@ void LLViewerWindow::resetSnapshotLoc() } // static +void LLViewerWindow::onSnapshotNotificationClick(const LLSD& notification, const LLSD& response) +{ + std::string filepath = notification["payload"]["filepath"].asString(); + if (!filepath.empty()) + { + gDirUtilp->openDir(filepath); + } +} + +// static void LLViewerWindow::movieSize(S32 new_width, S32 new_height) { LLCoordWindow size; diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index da2371f6fe..ec28a3fc4a 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -410,6 +410,7 @@ public: void resetSnapshotLoc(); void playSnapshotAnimAndSound(); + static void onSnapshotNotificationClick(const LLSD& notification, const LLSD& response); // draws selection boxes around selected objects, must call displayObjects first void renderSelections( bool for_gl_pick, bool pick_parcel_walls, bool for_hud ); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 59deead084..df198e8aed 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -9127,6 +9127,14 @@ Failed to save snapshot to [PATH]: Disk is full. [NEED_MEMORY]KB is required but Failed to save snapshot to [PATH]: Directory does not exist. </notification> + <notification icon="notifytip.tga" + name="SnapshotSavedToComputer" type="notifytip"> +Screenshot saved to: + [FILEPATH] + +Click to open folder. + </notification> + <notification icon="notifytip.tga" name="PresetNotSaved" |
