From 3f08dd5ddc292d83cda0006818353970a63c8fa6 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Sat, 18 Apr 2020 21:56:28 +0200 Subject: [PATCH] LibGUI: Add GUI::DesktopServices::open(URL) This API is used to open a URL in whatever way the desktop system feels is best. If you give it a file:// URL, it will try to work out a good application to open the URL with. For all other protocols, it will open a Browser instance. :^) --- Libraries/LibGUI/DesktopServices.cpp | 83 ++++++++++++++++++++++++++++ Libraries/LibGUI/DesktopServices.h | 38 +++++++++++++ Libraries/LibGUI/Makefile | 1 + 3 files changed, 122 insertions(+) create mode 100644 Libraries/LibGUI/DesktopServices.cpp create mode 100644 Libraries/LibGUI/DesktopServices.h diff --git a/Libraries/LibGUI/DesktopServices.cpp b/Libraries/LibGUI/DesktopServices.cpp new file mode 100644 index 00000000000..e994655cbfd --- /dev/null +++ b/Libraries/LibGUI/DesktopServices.cpp @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +namespace GUI { + +static bool open_file_url(const URL&); +static bool spawn(String executable, String argument); + +bool DesktopServices::open(const URL& url) +{ + if (url.protocol() == "file") + return open_file_url(url); + + return spawn("/bin/Browser", url.to_string()); +} + +bool spawn(String executable, String argument) +{ + if (fork() == 0) { + if (execl(executable.characters(), executable.characters(), argument.characters(), nullptr) < 0) { + perror("execl"); + return false; + } + ASSERT_NOT_REACHED(); + } + return true; +} + +bool open_file_url(const URL& url) +{ + struct stat st; + if (stat(url.path().characters(), &st) < 0) { + perror("stat"); + return false; + } + + if (S_ISDIR(st.st_mode)) + return spawn("/bin/FileManager", url.path()); + + if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) + return spawn(url.path(), {}); + + if (url.path().to_lowercase().ends_with(".png")) + return spawn("/bin/QuickShow", url.path()); + + if (url.path().to_lowercase().ends_with(".html")) + return spawn("/bin/Browser", url.path()); + + if (url.path().to_lowercase().ends_with(".wav")) + return spawn("/bin/SoundPlayer", url.path()); + + return spawn("/bin/TextEditor", url.path()); +} + +} diff --git a/Libraries/LibGUI/DesktopServices.h b/Libraries/LibGUI/DesktopServices.h new file mode 100644 index 00000000000..da91c70d18a --- /dev/null +++ b/Libraries/LibGUI/DesktopServices.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2020, Andreas Kling + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include + +namespace GUI { + +class DesktopServices { +public: + static bool open(const URL&); +}; + +} diff --git a/Libraries/LibGUI/Makefile b/Libraries/LibGUI/Makefile index 5156a15a4a0..cc90ba5c349 100644 --- a/Libraries/LibGUI/Makefile +++ b/Libraries/LibGUI/Makefile @@ -18,6 +18,7 @@ OBJS = \ CppLexer.o \ CppSyntaxHighlighter.o \ Desktop.o \ + DesktopServices.o \ Dialog.o \ DisplayLink.o \ DragOperation.o \