| 293 | } |
| 294 | |
| 295 | void OpenLink( const std::string& url ) |
| 296 | { |
| 297 | #ifdef _WIN32 |
| 298 | INT_PTR code = ( INT_PTR )ShellExecuteA( NULL, "open", url.c_str(), NULL, NULL, SW_SHOWNORMAL ); |
| 299 | if ( code <= 32 ) |
| 300 | { |
| 301 | // https://learn.microsoft.com/en-us/windows/win32/api/shellapi/nf-shellapi-shellexecutea |
| 302 | // value greater then 32 is OK, less value means error |
| 303 | spdlog::error( "Error opening link {}, error code {}: {}", url, code, GetLastError() ); |
| 304 | } |
| 305 | else |
| 306 | { |
| 307 | spdlog::info( "Opening link {}, return code {}", url, code ); |
| 308 | } |
| 309 | #else |
| 310 | #ifdef __EMSCRIPTEN__ |
| 311 | #pragma clang diagnostic push |
| 312 | #pragma clang diagnostic ignored "-Wdollar-in-identifier-extension" |
| 313 | EM_ASM( open_link( UTF8ToString( $0 ) ), url.c_str() ); |
| 314 | #pragma clang diagnostic pop |
| 315 | #else |
| 316 | // Single-quote the URL so the shell does not interpret characters common in query strings |
| 317 | // ('&', '?', ';', spaces, ...). Without quoting, everything after the first '&' is parsed as a |
| 318 | // separate command and dropped, truncating the opened URL. |
| 319 | const auto quoteForShell = []( const std::string& s ) |
| 320 | { |
| 321 | std::string result = "'"; |
| 322 | for ( char c : s ) |
| 323 | result += ( c == '\'' ) ? std::string( "'\\''" ) : std::string( 1, c ); |
| 324 | result += '\''; |
| 325 | return result; |
| 326 | }; |
| 327 | #ifdef __APPLE__ |
| 328 | auto openres = system( ( "open " + quoteForShell( url ) ).c_str() ); |
| 329 | #else |
| 330 | auto openres = system( ( "xdg-open " + quoteForShell( url ) + " &" ).c_str() ); |
| 331 | #endif |
| 332 | if ( openres == -1 ) |
| 333 | { |
| 334 | spdlog::warn( "Error opening {}", url ); |
| 335 | } |
| 336 | #endif |
| 337 | #endif // _WIN32 |
| 338 | } |
| 339 | |
| 340 | // Opens given file in associated application |
| 341 | bool OpenDocument( const std::filesystem::path& path ) |
no test coverage detected