summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llfilesystem/lldir.cpp47
-rw-r--r--indra/llfilesystem/lldir.h3
-rw-r--r--indra/newview/llpanelgenerictip.cpp8
-rw-r--r--indra/newview/llviewerwindow.cpp23
-rw-r--r--indra/newview/llviewerwindow.h1
-rw-r--r--indra/newview/skins/default/xui/en/notifications.xml8
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"