gio-0.13.11.0: System/GIO/File/AppInfo.chs
{-# LANGUAGE CPP #-}
-- GIMP Toolkit (GTK) Binding for Haskell: binding to gio -*-haskell-*-
--
-- Author : Andy Stewart
-- Created: 30-Apirl-2010
--
-- Copyright (c) 2010 Andy Stewart
--
-- This library is free software: you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public License
-- as published by the Free Software Foundation, either version 3 of
-- the License, or (at your option) any later version.
--
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
--
-- You should have received a copy of the GNU Lesser General Public
-- License along with this program. If not, see
-- <http://www.gnu.org/licenses/>.
--
-- GIO, the C library which this Haskell library depends on, is
-- available under LGPL Version 2. The documentation included with
-- this library is based on the original GIO documentation.
--
-- | Maintainer : gtk2hs-devel@lists.sourceforge.net
-- Stability : alpha
-- Portability : portable (depends on GHC)
module System.GIO.File.AppInfo (
-- * Details
-- | 'AppInfo' and 'AppLaunchContext' are used for describing and launching applications installed on the
-- system.
--
-- As of GLib 2.20, URIs will always be converted to POSIX paths (using 'fileGetPath' when using
-- 'appInfoLaunch' even if the application requested an URI and not a POSIX path. For example for
-- an desktop-file based application with Exec key totem %U and a single URI, sftp://foo/file.avi, then
-- /home/user/.gvfs/sftp on foo/file.avi will be passed. This will only work if a set of suitable GIO
-- extensions (such as gvfs 2.26 compiled with FUSE support), is available and operational; if this is
-- not the case, the URI will be passed unmodified to the application. Some URIs, such as mailto:, of
-- course cannot be mapped to a POSIX path (in gvfs there's no FUSE mount for it); such URIs will be
-- passed unmodified to the application.
--
-- Specifically for gvfs 2.26 and later, the POSIX URI will be mapped back to the GIO URI in the 'File'
-- constructors (since gvfs implements the GVfs extension point). As such, if the application needs to
-- examine the URI, it needs to use 'fileGetUri' or similar on 'File'. In other words, an
-- application cannot assume that the URI passed to e.g. 'fileNewForCommandlineArg ' is equal to
-- the result of 'fileGetUri'.
-- * Types
AppInfo,
AppInfoClass,
AppLaunchContext,
AppLaunchContextClass,
-- * Enums
AppInfoCreateFlags (..),
-- * Methods
appInfoCreateFromCommandline,
appInfoDup,
appInfoEqual,
appInfoGetId,
appInfoGetName,
#if GLIB_CHECK_VERSION(2,24,0)
appInfoGetDisplayName,
#endif
appInfoGetDescription,
appInfoGetExecutable,
#if GLIB_CHECK_VERSION(2,20,0)
appInfoGetCommandline,
#endif
appInfoGetIcon,
appInfoLaunch,
appInfoSupportsFiles,
appInfoSupportsUris,
appInfoLaunchUris,
appInfoShouldShow,
#if GLIB_CHECK_VERSION(2,20,0)
appInfoCanDelete,
appInfoDelete,
appInfoResetTypeAssociations,
#endif
appInfoSetAsDefaultForType,
appInfoSetAsDefaultForExtension,
appInfoAddSupportsType,
appInfoCanRemoveSupportsType,
appInfoRemoveSupportsType,
appInfoGetAll,
appInfoGetAllForType,
appInfoGetDefaultForType,
appInfoGetDefaultForUriScheme,
appInfoLaunchDefaultForUri,
appLaunchContextGetDisplay,
appLaunchContextGetStartupNotifyId,
appLaunchContextLaunchFailed,
appLaunchContextNew
) where
import Control.Monad
import Data.Maybe (fromMaybe)
import Data.ByteString (ByteString)
import Data.ByteString.Unsafe (unsafePackCStringFinalizer)
import System.GIO.Enums
import System.Glib.FFI
import System.Glib.Flags
import System.Glib.GError
import System.Glib.GList
import System.Glib.GObject
import System.Glib.UTFString
{#import System.GIO.Types#}
{# context lib = "gio" prefix = "g" #}
-- | Creates a new 'AppInfo' from the given information.
appInfoCreateFromCommandline ::
GlibString string
=> string -- ^ @commandline@ the commandline to use
-> Maybe string -- ^ @applicationName@ the application name, or 'Nothing' to use commandline
-> [AppInfoCreateFlags] -- ^ @flags@ flags that can specify details of the created 'AppInfo'
-> IO AppInfo -- ^ returns new 'AppInfo' for given command.
appInfoCreateFromCommandline commandline applicationName flags =
wrapNewGObject mkAppInfo $
withUTFString commandline $ \ commandlinePtr ->
maybeWith withUTFString applicationName $ \ applicationNamePtr ->
propagateGError ({#call g_app_info_create_from_commandline #}
commandlinePtr
applicationNamePtr
((fromIntegral . fromFlags) flags))
-- | Creates a duplicate of a 'AppInfo'.
appInfoDup :: AppInfoClass appinfo => appinfo -> IO AppInfo
appInfoDup appinfo =
wrapNewGObject mkAppInfo $
{#call g_app_info_dup #} (toAppInfo appinfo)
-- | Checks if two 'AppInfo's are equal.
appInfoEqual :: (AppInfoClass info1, AppInfoClass info2) => info1 -> info2
-> Bool -- ^ returns 'True' if appinfo1 is equal to appinfo2. 'False' otherwise.
appInfoEqual info1 info2 =
unsafePerformIO $ liftM toBool $
{#call g_app_info_equal #} (toAppInfo info1) (toAppInfo info2)
-- | Gets the ID of an application. An id is a string that identifies the application. The exact format
-- of the id is platform dependent. For instance, on Unix this is the desktop file id from the xdg menu
-- specification.
--
-- Note that the returned ID may be 'Nothing', depending on how the appinfo has been constructed.
appInfoGetId :: (AppInfoClass appinfo, GlibString string)
=> appinfo
-> IO (Maybe string)
appInfoGetId appinfo =
{#call g_app_info_get_id#} (toAppInfo appinfo)
>>= maybePeek readUTFString
-- | Gets the installed name of the application.
appInfoGetName :: AppInfoClass appinfo => appinfo
-> String -- ^ returns the name of the application for appinfo.
appInfoGetName appinfo =
unsafePerformIO $
{#call g_app_info_get_name#} (toAppInfo appinfo)
>>= readCString
#if GLIB_CHECK_VERSION(2,24,0)
-- | Gets the installed name of the application.
appInfoGetDisplayName :: (AppInfoClass appinfo, GlibString string)
=> appinfo
-> string -- ^ returns the display name of the application for appinfo, or the name if no display name is available.
appInfoGetDisplayName appinfo =
unsafePerformIO $
{#call g_app_info_get_display_name#} (toAppInfo appinfo)
>>= readUTFString
#endif
-- | Gets a human-readable description of an installed application.
appInfoGetDescription :: (AppInfoClass appinfo, GlibString string)
=> appinfo
-> Maybe string -- ^ returns a string containing a description of the application appinfo, or 'Nothing' if none.
appInfoGetDescription appinfo =
unsafePerformIO $ do
{#call g_app_info_get_description#} (toAppInfo appinfo)
>>= maybePeek peekUTFString
-- | Gets the executable's name for the installed application.
appInfoGetExecutable :: (AppInfoClass appinfo, GlibString string)
=> appinfo
-> string -- ^ returns the executable of the application for appinfo.
appInfoGetExecutable appinfo =
unsafePerformIO $
{#call g_app_info_get_executable#} (toAppInfo appinfo)
>>= peekUTFString
#if GLIB_CHECK_VERSION(2,20,0)
-- | Gets the commandline with which the application will be started.
appInfoGetCommandline :: AppInfoClass appinfo => appinfo
-> Maybe ByteString -- ^ returns a string containing the appinfo's commandline, or 'Nothing' if this information is not available
appInfoGetCommandline appinfo =
unsafePerformIO $ do
sPtr <- {#call g_app_info_get_commandline#} (toAppInfo appinfo)
if sPtr == nullPtr
then return Nothing
else do
sLen <- lengthArray0 0 sPtr
liftM Just $ unsafePackCStringFinalizer (castPtr sPtr) (fromIntegral sLen)
({#call unsafe g_free#} (castPtr sPtr))
#endif
-- | Gets the icon for the application.
appInfoGetIcon :: AppInfoClass appinfo => appinfo
-> IO (Maybe Icon) -- ^ returns the default 'Icon' for appinfo or 'Nothing'
appInfoGetIcon appinfo =
maybeNull (makeNewGObject mkIcon) $
{#call g_app_info_get_icon#} (toAppInfo appinfo)
-- | Launches the application. Passes files to the launched application as arguments, using the optional
-- @launchContext@ to get information about the details of the launcher (like what screen it is on).
-- Throws a 'GError' if an error occurs
--
-- To launch the application without arguments pass a empty files list.
--
-- Note that even if the launch is successful the application launched can fail to start if it runs
-- into problems during startup. There is no way to detect this.
--
-- Some URIs can be changed when passed through a 'File' (for instance unsupported uris with strange
-- formats like mailto:), so if you have a textual uri you want to pass in as argument, consider using
-- 'appInfoLaunchUris' instead.
appInfoLaunch :: AppInfoClass appinfo => appinfo
-> [File] -- ^ @files@ a list of 'File' objects
-> Maybe AppLaunchContext -- ^ @launchContext@ a 'AppLaunchContext' or 'Nothing'
-> IO ()
appInfoLaunch appinfo files launchContext =
withForeignPtrs (map unFile files) $ \wFilePtr ->
withGList wFilePtr $ \filesPtr ->
propagateGError (\gErrorPtr -> do
{#call g_app_info_launch#}
(toAppInfo appinfo)
filesPtr
(fromMaybe (AppLaunchContext nullForeignPtr) launchContext)
gErrorPtr
return ())
-- | Checks if the application accepts files as arguments.
appInfoSupportsFiles :: AppInfoClass appinfo => appinfo
-> IO Bool -- ^ returns 'True' if the appinfo supports files.
appInfoSupportsFiles appinfo =
liftM toBool $
{#call g_app_info_supports_files #} (toAppInfo appinfo)
-- | Checks if the application accepts uris as arguments.
appInfoSupportsUris :: AppInfoClass appinfo => appinfo
-> IO Bool -- ^ returns 'True' if the appinfo supports uris.
appInfoSupportsUris appinfo =
liftM toBool $
{#call g_app_info_supports_uris #} (toAppInfo appinfo)
-- | Launches the application. Passes uris to the launched application as arguments, using the optional
-- @launchContext@ to get information about the details of the launcher (like what screen it is on).
-- Throws a 'GError' if an error occurs.
--
-- To launch the application without arguments pass a empty uris list.
--
-- Note that even if the launch is successful the application launched can fail to start if it runs
-- into problems during startup. There is no way to detect this.
appInfoLaunchUris :: (AppInfoClass appinfo, GlibString string)
=> appinfo
-> [string] -- ^ @uris@ a list containing URIs to launch.
-> Maybe AppLaunchContext -- ^ @launchContext@ a 'AppLaunchContext' or 'Nothing'
-> IO ()
appInfoLaunchUris appinfo uris launchContext =
withUTFStringArray uris $ \urisPtr ->
propagateGError (\gErrorPtr -> do
{#call g_app_info_launch_uris#}
(toAppInfo appinfo)
(castPtr urisPtr)
(fromMaybe (AppLaunchContext nullForeignPtr) launchContext)
gErrorPtr
return ())
-- | Checks if the application info should be shown in menus that list available applications.
appInfoShouldShow :: AppInfoClass appinfo => appinfo
-> IO Bool -- ^ returns 'True' if the appinfo should be shown, 'False' otherwise.
appInfoShouldShow appinfo =
liftM toBool $
{#call g_app_info_should_show#} (toAppInfo appinfo)
#if GLIB_CHECK_VERSION(2,20,0)
-- | Obtains the information whether the 'AppInfo' can be deleted. See 'appInfoDelete'.
appInfoCanDelete :: AppInfoClass appinfo => appinfo
-> IO Bool -- ^ returns 'True' if appinfo can be deleted
appInfoCanDelete appinfo =
liftM toBool $
{#call g_app_info_can_delete#} (toAppInfo appinfo)
-- | Tries to delete a 'AppInfo'.
--
-- On some platforms, there may be a difference between user-defined 'AppInfo's which can be deleted,
-- and system-wide ones which cannot. See 'appInfoCanDelete'.
appInfoDelete :: AppInfoClass appinfo => appinfo
-> IO Bool -- ^ returns 'True' if appinfo has been deleted
appInfoDelete appinfo =
liftM toBool $
{#call g_app_info_delete#} (toAppInfo appinfo)
-- | Removes all changes to the type associations done by 'appInfoSetAsDefaultForType',
-- 'appInfoSetAsDefaultForExtension' or
-- 'appInfoRemoveSupportsType'.
appInfoResetTypeAssociations ::
GlibString string
=> string -- ^ @contentType@ a content type
-> IO ()
appInfoResetTypeAssociations contentType =
withUTFString contentType $ \ contentTypePtr ->
{#call g_app_info_reset_type_associations#} (castPtr contentTypePtr)
#endif
-- | Sets the application as the default handler for a given type.
-- Throws a 'GError' if an error occurs.
appInfoSetAsDefaultForType :: (AppInfoClass appinfo, GlibString string)
=> appinfo
-> string -- ^ @contentType@ the content type.
-> IO ()
appInfoSetAsDefaultForType appinfo contentType =
withUTFString contentType $ \ contentTypePtr ->
propagateGError (\gErrorPtr -> do
{#call g_app_info_set_as_default_for_type#}
(toAppInfo appinfo)
(castPtr contentTypePtr)
gErrorPtr
return ())
-- | Sets the application as the default handler for a given extension.
-- Throws a 'GError' if an error occurs.
appInfoSetAsDefaultForExtension :: (AppInfoClass appinfo, GlibString string)
=> appinfo
-> string -- ^ @extension@ a string containing the file extension (without the dot).
-> IO ()
appInfoSetAsDefaultForExtension appinfo extension =
withUTFString extension $ \ extensionPtr ->
propagateGError (\gErrorPtr -> do
{#call g_app_info_set_as_default_for_extension #}
(toAppInfo appinfo)
(castPtr extensionPtr)
gErrorPtr
return ())
-- | Adds a content type to the application information to indicate the application is capable of opening
-- files with the given content type.
-- Throws a 'GError' if an error occurs.
appInfoAddSupportsType :: (AppInfoClass appinfo, GlibString string)
=> appinfo
-> string -- ^ @contentType@ a string.
-> IO ()
appInfoAddSupportsType appinfo extension =
withUTFString extension $ \ extensionPtr ->
propagateGError (\gErrorPtr -> do
{#call g_app_info_add_supports_type#}
(toAppInfo appinfo)
(castPtr extensionPtr)
gErrorPtr
return ())
-- | Checks if a supported content type can be removed from an application.
appInfoCanRemoveSupportsType :: AppInfoClass appinfo => appinfo
-> IO Bool -- ^ returns 'True' if it is possible to remove supported content types from a given appinfo, 'False' if not.
appInfoCanRemoveSupportsType appinfo =
liftM toBool $
{#call g_app_info_can_remove_supports_type#} (toAppInfo appinfo)
-- | Removes a supported type from an application, if possible.
-- Throws a 'GError' if an error occurs.
appInfoRemoveSupportsType :: (AppInfoClass appinfo, GlibString string)
=> appinfo
-> string -- ^ @contentType@ a string.
-> IO ()
appInfoRemoveSupportsType appinfo extension =
withUTFString extension $ \ extensionPtr ->
propagateGError (\gErrorPtr -> do
{#call g_app_info_remove_supports_type#}
(toAppInfo appinfo)
(castPtr extensionPtr)
gErrorPtr
return ())
-- | Gets a list of all of the applications currently registered on this system.
--
-- For desktop files, this includes applications that have NoDisplay=true set or are excluded from
-- display by means of OnlyShowIn or NotShowIn. See 'appInfoShouldShow'. The returned list does
-- not include applications which have the Hidden key set.
appInfoGetAll :: IO [AppInfo]
appInfoGetAll = do
glistPtr <- {# call g_app_info_get_all #}
list <- fromGList glistPtr
mapM (wrapNewGObject mkAppInfo . return) list
-- | Gets a list of all 'AppInfo's for a given content type.
appInfoGetAllForType ::
GlibString string
=> string -- ^ @contentType@ the content type to find a 'AppInfo' for
-> IO [AppInfo] -- ^ returns list of 'AppInfo's for given @contentType@ or 'empty' on error.
appInfoGetAllForType contentType =
withUTFString contentType $ \ contentTypePtr -> do
glistPtr <- {# call g_app_info_get_all_for_type #} (castPtr contentTypePtr)
if glistPtr == nullPtr
then return []
else do
list <- fromGList glistPtr
mapM (wrapNewGObject mkAppInfo . return) list
-- | Gets the 'AppInfo' that corresponds to a given content type.
appInfoGetDefaultForType ::
GlibString string
=> string -- ^ @contentType@ the content type to find a 'AppInfo' for
-> Bool -- ^ @mustSupportUris@ if 'True', the 'AppInfo' is expected to support URIs
-> IO (Maybe AppInfo) -- ^ returns list of 'AppInfo's for given @contentType@ or 'Nothing' on error.
appInfoGetDefaultForType contentType mustSupportUris =
maybeNull (wrapNewGObject mkAppInfo) $
withUTFString contentType $ \ contentTypePtr -> do
{# call g_app_info_get_default_for_type #}
(castPtr contentTypePtr)
(fromBool mustSupportUris)
-- | Gets the default application for launching applications using this URI scheme. A URI scheme is the
-- initial part of the URI, up to but not including the ':', e.g. "http", "ftp" or "sip".
appInfoGetDefaultForUriScheme ::
GlibString string
=> string -- ^ @uriScheme@ a string containing a URI scheme.
-> IO (Maybe AppInfo) -- ^ returns list of 'AppInfo's for given @contentType@ or 'Nothing' on error.
appInfoGetDefaultForUriScheme uriScheme =
maybeNull (wrapNewGObject mkAppInfo) $
withUTFString uriScheme $ \ uriSchemePtr ->
{# call g_app_info_get_default_for_uri_scheme #} (castPtr uriSchemePtr)
-- | Utility function that launches the default application registered to handle the specified
-- uri. Synchronous I/O is done on the uri to detect the type of the file if required.
-- Throws a 'GError' if an error occurs.
appInfoLaunchDefaultForUri ::
GlibString string
=> string -- ^ @uri@ the uri to show
-> AppLaunchContext -- ^ @launchContext@ an optional 'AppLaunchContext'.
-> IO ()
appInfoLaunchDefaultForUri uri launchContext =
withUTFString uri $ \ uriPtr ->
propagateGError (\gErrorPtr -> do
{#call g_app_info_launch_default_for_uri#}
(castPtr uriPtr)
launchContext
gErrorPtr
return ())
-- | Gets the display string for the display. This is used to ensure new applications are started on the
-- same display as the launching application.
appLaunchContextGetDisplay :: (AppInfoClass appinfo, GlibString string)
=> AppLaunchContext
-> appinfo
-> [File] -- ^ @files@ a list of 'File' objects
-> IO string -- ^ returns a display string for the display.
appLaunchContextGetDisplay launchContext appinfo files =
withForeignPtrs (map unFile files) $ \wFilePtr ->
withGList wFilePtr $ \filesPtr ->
{#call g_app_launch_context_get_display#}
(toAppLaunchContext launchContext)
(toAppInfo appinfo)
filesPtr
>>= readUTFString
-- | Initiates startup notification for the application and returns the DesktopStartupId for the
-- launched operation, if supported.
--
-- Startup notification IDs are defined in the FreeDesktop.Org Startup Notifications standard.
appLaunchContextGetStartupNotifyId :: (AppInfoClass appinfo, GlibString string)
=> AppLaunchContext
-> appinfo
-> [File] -- ^ @files@ a list of 'File' objects
-> IO (Maybe string) -- ^ returns a startup notification ID for the application, or 'Nothing' if not supported.
appLaunchContextGetStartupNotifyId launchContext appinfo files =
withForeignPtrs (map unFile files) $ \wFilePtr ->
withGList wFilePtr $ \filesPtr ->
{#call g_app_launch_context_get_startup_notify_id #}
(toAppLaunchContext launchContext)
(toAppInfo appinfo)
filesPtr
>>= maybePeek readUTFString
-- | Called when an application has failed to launch, so that it can cancel the application startup
-- notification started in 'appLaunchContextGetStartupNotifyId'.
appLaunchContextLaunchFailed :: GlibString string
=> AppLaunchContext
-> string -- ^ @startupNotifyId@ the startup notification id that was returned by 'appLaunchContextGetStartupNotifyId'.
-> IO ()
appLaunchContextLaunchFailed launchContext startupNotifyId =
withUTFString startupNotifyId $ \ startupNotifyIdPtr ->
{#call g_app_launch_context_launch_failed#}
(toAppLaunchContext launchContext)
(castPtr startupNotifyIdPtr)
-- | Creates a new application launch context. This is not normally used, instead you instantiate a
-- subclass of this, such as 'AppLaunchContext'.
appLaunchContextNew :: IO AppLaunchContext
appLaunchContextNew =
wrapNewGObject mkAppLaunchContext $
{#call g_app_launch_context_new#}