include/sfx2/strings.hrc        |    3 +
 sfx2/source/dialog/bluthsnd.cxx |  109 +++++++++++++++++++++++++++++++++++++---
 sfx2/source/view/viewsh.cxx     |    2 
 3 files changed, 106 insertions(+), 8 deletions(-)

New commits:
commit f26f9b8e22cdbcfc6fff7a31f61bbc303ff2fb90
Author:     Ujjawal Kumar <[email protected]>
AuthorDate: Tue Jan 13 03:10:30 2026 +0530
Commit:     Hossein <[email protected]>
CommitDate: Fri Jan 30 00:43:56 2026 +0100

    tdf#58454 Fix Bluetooth transfer on Linux and macOS devices
    
    This patch fixes Bluetooth transfers by utilizing desktop environment
    specific stacks on Linux and the native 'Bluetooth File Exchange'
    application on macOS.
    
    Change-Id: I602033b8a798a9309ead2eba55e693c3f0a84e33
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/197152
    Tested-by: Jenkins
    Reviewed-by: Hossein <[email protected]>

diff --git a/include/sfx2/strings.hrc b/include/sfx2/strings.hrc
index e39c7fb8efec..b892ce42478e 100644
--- a/include/sfx2/strings.hrc
+++ b/include/sfx2/strings.hrc
@@ -257,6 +257,9 @@
 #define STR_PRINT_NEWORISIZE                    NC_("STR_PRINT_NEWORISIZE", 
"The page size and orientation have been modified.
Would you like to save the new settings in the
active document?")
 #define STR_CANT_CLOSE                          NC_("STR_CANT_CLOSE", "The 
document cannot be closed because a
 print job is being carried out.")
 #define STR_ERROR_SEND_MAIL                     NC_("STR_ERROR_SEND_MAIL", "An 
error occurred in sending the message. Possible errors could be a missing user 
account or a defective setup.
Please check the %PRODUCTNAME settings or your email program settings.")
+#define STR_BLUETOOTH_PACKAGE_ERROR_LINUX       
NC_("STR_BLUETOOTH_PACKAGE_ERROR", "The Bluetooth transfer tool '%TOOL' could 
not be found on the system.
Please install the '%PKG' package for your distribution.")
+#define STR_BLUETOOTH_ERROR_MACOS               
NC_("STR_BLUETOOTH_ERROR_MACOS", "Failed to open %TOOL.")
+#define STR_BLUETOOTH_SEND_ERROR                
NC_("STR_BLUETOOTH_SEND_ERROR", "Sending document via Bluetooth failed.")
 // Error codes look like "MAPI_E_FAILURE" or "1234"
 #define STR_ERROR_SEND_MAIL_CODE                
NC_("STR_ERROR_SEND_MAIL_CODE", "An error occurred in sending the message. 
Possible errors could be a missing user account or a defective setup.

Error code is $1")
 #define STR_ERROR_SEND_MAIL_HEADER              
NC_("STR_ERROR_SEND_MAIL_HEADER", "Error sending mail")
diff --git a/sfx2/source/dialog/bluthsnd.cxx b/sfx2/source/dialog/bluthsnd.cxx
index 0083f0749768..111da6749cde 100644
--- a/sfx2/source/dialog/bluthsnd.cxx
+++ b/sfx2/source/dialog/bluthsnd.cxx
@@ -9,9 +9,17 @@
 
 #include <com/sun/star/frame/XFrame.hpp>
 
-#include <stdio.h>
-
 #include <bluthsndapi.hxx>
+#include <osl/file.hxx>
+#include <sfx2/app.hxx>
+#include <sfx2/sfxresid.hxx>
+#include <sfx2/strings.hrc>
+#include <vcl/svapp.hxx>
+#include <vcl/weld/weld.hxx>
+
+#if defined(LINUX) || defined(MACOSX)
+#include <sys/wait.h>
+#endif
 
 SfxBluetoothModel::SendMailResult SfxBluetoothModel::SaveAndSend( const 
css::uno::Reference< css::frame::XFrame >& xFrame )
 {
@@ -33,16 +41,103 @@ SfxBluetoothModel::SendMailResult 
SfxBluetoothModel::SaveAndSend( const css::uno
 
 SfxBluetoothModel::SendMailResult SfxBluetoothModel::Send()
 {
-#ifndef LINUX
+#if !defined(LINUX) && !defined(MACOSX)
     (void) this; // avoid loplugin:staticmethods
     return SEND_MAIL_ERROR;
 #else
-    char bthsend[300];
+#ifdef LINUX
+    //KDE
+    static constexpr OUString KdePackageName = u"bluedevil"_ustr;
+    static constexpr OUString KdeToolName = u"bluedevil-sendfile"_ustr;
+
+    //Gnome
+    static constexpr OUString GnomePackageName = u"gnome-bluetooth"_ustr;
+    static constexpr OUString GnomeToolName = u"bluetooth-sendto"_ustr;
+
+    //XFCE and LXQT
+    static constexpr OUString Xfce_Lxqt_PackageName = u"blueman"_ustr;
+    static constexpr OUString Xfce_Lxqt_ToolName = u"blueman-sendto"_ustr;
+
+    //Mate
+    static constexpr OUString MatePackageName = u"blueberry"_ustr;
+    static constexpr OUString MateToolName = u"blueberry-sendto"_ustr;
+
+    static constexpr int CommandNotFound = 127;
+#elif defined(MACOSX)
+    //macOS
+    static constexpr OUString MacToolName = u"Bluetooth File Exchange"_ustr;
+#endif
+
     SendMailResult eResult = SEND_MAIL_OK;
-    OUString aFileName = maAttachedDocuments[0];
-    snprintf(bthsend,300,"bluetooth-sendto %s",OUStringToOString( aFileName, 
RTL_TEXTENCODING_UTF8).getStr() );
-    if( !system( bthsend ) )
+    OUString aFilePath = maAttachedDocuments.back();
+    OUString aSystemPath;
+
+    osl::File::getSystemPathFromFileURL(aFilePath, aSystemPath);
+
+    OUString aSendCommand;
+    OUString aToolName;
+#ifdef LINUX
+    OUString aPackageName;
+    OUString aDesktopEnvironment = Application::GetDesktopEnvironment();
+
+    if(aDesktopEnvironment == u"PLASMA5"_ustr || aDesktopEnvironment == 
u"PLASMA6"_ustr)
+    {
+        aPackageName = KdePackageName;
+        aToolName =  KdeToolName;
+        aSendCommand = aToolName + " -f " + aSystemPath;
+    }
+    else if(aDesktopEnvironment == u"GNOME"_ustr)
+    {
+        aPackageName = GnomePackageName;
+        aToolName = GnomeToolName;
+        aSendCommand = aToolName + " " + aSystemPath;
+    }
+    else if(aDesktopEnvironment == u"XFCE"_ustr || aDesktopEnvironment == 
u"LXQT"_ustr)
+    {
+        aPackageName = Xfce_Lxqt_PackageName;
+        aToolName = Xfce_Lxqt_ToolName;
+        aSendCommand = aToolName + " " + aSystemPath;
+    }
+    else if(aDesktopEnvironment == u"MATE"_ustr)
+    {
+        aPackageName = MatePackageName;
+        aToolName = MateToolName;
+        aSendCommand = aToolName + " " + aSystemPath;
+    }
+#elif defined(MACOSX)
+    aToolName = MacToolName;
+    aSendCommand = "open -a \"" + aToolName + "\" " + aSystemPath;
+#endif
+
+    OString aRawCommand = OUStringToOString( aSendCommand, 
RTL_TEXTENCODING_UTF8);
+
+    int status = system(aRawCommand.getStr());
+    if (status == -1 ||
+        !WIFEXITED(status) ||
+        WEXITSTATUS(status) != 0)
+    {
         eResult = SEND_MAIL_ERROR;
+        OUString errMsg;
+
+#ifdef LINUX
+        if(WIFEXITED(status) && WEXITSTATUS(status) == CommandNotFound)
+        {
+            errMsg = SfxResId(STR_BLUETOOTH_PACKAGE_ERROR_LINUX)
+                                .replaceAll("%TOOL", aToolName)
+                                .replaceAll("%PKG", aPackageName);
+        }
+#elif defined(MACOSX)
+        errMsg = SfxResId(STR_BLUETOOTH_ERROR_MACOS).replaceAll("%TOOL", 
aToolName);
+#endif
+
+        if(!errMsg.isEmpty())
+        {
+            weld::Window* pWin = SfxGetpApp()->GetTopWindow();
+            std::unique_ptr<weld::MessageDialog> 
xBox(Application::CreateMessageDialog(
+                pWin, VclMessageType::Info, VclButtonsType::Ok, errMsg));
+            xBox->run();
+        }
+    }
     return eResult;
 #endif
 }
diff --git a/sfx2/source/view/viewsh.cxx b/sfx2/source/view/viewsh.cxx
index 3de0707f0a92..5e5c287f3970 100644
--- a/sfx2/source/view/viewsh.cxx
+++ b/sfx2/source/view/viewsh.cxx
@@ -2188,7 +2188,7 @@ void SfxViewShell::ExecMisc_Impl( SfxRequest &rReq )
                 weld::Window* pWin = SfxGetpApp()->GetTopWindow();
                 std::unique_ptr<weld::MessageDialog> 
xBox(Application::CreateMessageDialog(pWin,
                                                                          
VclMessageType::Info, VclButtonsType::Ok,
-                                                                         
SfxResId(STR_ERROR_SEND_MAIL)));
+                                                                         
SfxResId(STR_BLUETOOTH_SEND_ERROR)));
                 xBox->run();
                 rReq.Ignore();
             }

Reply via email to