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(); }
