mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-24 19:22:11 +01:00
Implement GContentType on OSX
This is an implementation of most of GContentType using the OS X UTType APIs. Missing at this point is an implementation of g_content_types_get_registered() and g_content_type_guess_for_tree(). https://bugzilla.gnome.org/show_bug.cgi?id=734946
This commit is contained in:
parent
626e9e6b6e
commit
42ed4e93ac
@ -3,8 +3,10 @@ include $(top_srcdir)/glib.mk
|
|||||||
SUBDIRS = gdbus-2.0/codegen
|
SUBDIRS = gdbus-2.0/codegen
|
||||||
|
|
||||||
if OS_UNIX
|
if OS_UNIX
|
||||||
|
if !OS_COCOA
|
||||||
SUBDIRS += xdgmime
|
SUBDIRS += xdgmime
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
if OS_WIN32_AND_DLL_COMPILATION
|
if OS_WIN32_AND_DLL_COMPILATION
|
||||||
if MS_LIB_AVAILABLE
|
if MS_LIB_AVAILABLE
|
||||||
@ -221,6 +223,7 @@ local_sources = \
|
|||||||
platform_libadd =
|
platform_libadd =
|
||||||
platform_deps =
|
platform_deps =
|
||||||
appinfo_sources =
|
appinfo_sources =
|
||||||
|
contenttype_sources =
|
||||||
|
|
||||||
if HAVE_INOTIFY
|
if HAVE_INOTIFY
|
||||||
SUBDIRS += inotify
|
SUBDIRS += inotify
|
||||||
@ -247,9 +250,13 @@ SUBDIRS += fam
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if OS_UNIX
|
if OS_UNIX
|
||||||
unix_appinfo_sources = gdesktopappinfo.c
|
if !OS_COCOA
|
||||||
platform_libadd += xdgmime/libxdgmime.la
|
platform_libadd += xdgmime/libxdgmime.la
|
||||||
platform_deps += xdgmime/libxdgmime.la
|
platform_deps += xdgmime/libxdgmime.la
|
||||||
|
endif
|
||||||
|
|
||||||
|
appinfo_sources += gdesktopappinfo.c
|
||||||
|
|
||||||
unix_sources = \
|
unix_sources = \
|
||||||
gfiledescriptorbased.c \
|
gfiledescriptorbased.c \
|
||||||
gunixconnection.c \
|
gunixconnection.c \
|
||||||
@ -266,7 +273,6 @@ unix_sources = \
|
|||||||
gunixvolumemonitor.h \
|
gunixvolumemonitor.h \
|
||||||
gunixinputstream.c \
|
gunixinputstream.c \
|
||||||
gunixoutputstream.c \
|
gunixoutputstream.c \
|
||||||
gcontenttype.c \
|
|
||||||
gcontenttypeprivate.h \
|
gcontenttypeprivate.h \
|
||||||
gfdonotificationbackend.c \
|
gfdonotificationbackend.c \
|
||||||
ggtknotificationbackend.c \
|
ggtknotificationbackend.c \
|
||||||
@ -321,7 +327,6 @@ win32_actual_sources = \
|
|||||||
$(gdbus_daemon_sources) \
|
$(gdbus_daemon_sources) \
|
||||||
gwin32registrykey.c \
|
gwin32registrykey.c \
|
||||||
gwin32registrykey.h \
|
gwin32registrykey.h \
|
||||||
gcontenttype-win32.c \
|
|
||||||
gwin32mount.c \
|
gwin32mount.c \
|
||||||
gwin32mount.h \
|
gwin32mount.h \
|
||||||
gwin32volumemonitor.c \
|
gwin32volumemonitor.c \
|
||||||
@ -344,6 +349,8 @@ win32_more_sources_for_vcproj = \
|
|||||||
|
|
||||||
if OS_WIN32
|
if OS_WIN32
|
||||||
win32_appinfo_sources = gwin32appinfo.c gwin32appinfo.h
|
win32_appinfo_sources = gwin32appinfo.c gwin32appinfo.h
|
||||||
|
appinfo_sources += gwin32appinfo.c gwin32appinfo.h
|
||||||
|
contenttype_sources += contenttype-win32.c
|
||||||
platform_libadd += -lshlwapi -lws2_32 -ldnsapi -liphlpapi
|
platform_libadd += -lshlwapi -lws2_32 -ldnsapi -liphlpapi
|
||||||
win32_sources = $(win32_actual_sources)
|
win32_sources = $(win32_actual_sources)
|
||||||
appinfo_sources += $(win32_appinfo_sources)
|
appinfo_sources += $(win32_appinfo_sources)
|
||||||
@ -387,6 +394,16 @@ portal_sources = \
|
|||||||
$(xdp_dbus_built_sources) \
|
$(xdp_dbus_built_sources) \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
if OS_COCOA
|
||||||
|
contenttype_sources += gosxcontenttype.c
|
||||||
|
endif
|
||||||
|
|
||||||
|
if OS_UNIX
|
||||||
|
if !OS_COCOA
|
||||||
|
contenttype_sources += gcontenttype.c
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
gio_base_sources = \
|
gio_base_sources = \
|
||||||
gappinfo.c \
|
gappinfo.c \
|
||||||
gappinfoprivate.h \
|
gappinfoprivate.h \
|
||||||
@ -542,6 +559,7 @@ gio_base_sources = \
|
|||||||
libgio_2_0_la_SOURCES = \
|
libgio_2_0_la_SOURCES = \
|
||||||
$(gio_base_sources) \
|
$(gio_base_sources) \
|
||||||
$(appinfo_sources) \
|
$(appinfo_sources) \
|
||||||
|
$(contenttype_sources) \
|
||||||
$(unix_sources) \
|
$(unix_sources) \
|
||||||
$(win32_sources) \
|
$(win32_sources) \
|
||||||
$(settings_sources) \
|
$(settings_sources) \
|
||||||
|
@ -46,6 +46,8 @@
|
|||||||
* On Win32 it is an extension string like ".doc", ".txt" or a perceived
|
* On Win32 it is an extension string like ".doc", ".txt" or a perceived
|
||||||
* string like "audio". Such strings can be looked up in the registry at
|
* string like "audio". Such strings can be looked up in the registry at
|
||||||
* HKEY_CLASSES_ROOT.
|
* HKEY_CLASSES_ROOT.
|
||||||
|
* On OSX it is a [Uniform Type Identifier](https://en.wikipedia.org/wiki/Uniform_Type_Identifier)
|
||||||
|
* such as "com.apple.application".
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
@ -187,7 +189,8 @@ g_content_type_is_mime_type (const gchar *type,
|
|||||||
*
|
*
|
||||||
* Checks if the content type is the generic "unknown" type.
|
* Checks if the content type is the generic "unknown" type.
|
||||||
* On UNIX this is the "application/octet-stream" mimetype,
|
* On UNIX this is the "application/octet-stream" mimetype,
|
||||||
* while on win32 it is "*".
|
* while on win32 it is "*" and on OSX it is a dynamic type
|
||||||
|
* or octet-stream.
|
||||||
*
|
*
|
||||||
* Returns: %TRUE if the type is the unknown type.
|
* Returns: %TRUE if the type is the unknown type.
|
||||||
*/
|
*/
|
||||||
|
@ -1259,7 +1259,7 @@ get_content_type (const char *basename,
|
|||||||
|
|
||||||
content_type = g_content_type_guess (basename, NULL, 0, &result_uncertain);
|
content_type = g_content_type_guess (basename, NULL, 0, &result_uncertain);
|
||||||
|
|
||||||
#ifndef G_OS_WIN32
|
#if !defined(G_OS_WIN32) && !defined(HAVE_COCOA)
|
||||||
if (!fast && result_uncertain && path != NULL)
|
if (!fast && result_uncertain && path != NULL)
|
||||||
{
|
{
|
||||||
guchar sniff_buffer[4096];
|
guchar sniff_buffer[4096];
|
||||||
|
423
gio/gosxcontenttype.c
Normal file
423
gio/gosxcontenttype.c
Normal file
@ -0,0 +1,423 @@
|
|||||||
|
/* GIO - GLib Input, Output and Streaming Library
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Patrick Griffis
|
||||||
|
*
|
||||||
|
* 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 2 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 library; if not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include "gcontenttype.h"
|
||||||
|
#include "gicon.h"
|
||||||
|
#include "gthemedicon.h"
|
||||||
|
|
||||||
|
#include <CoreServices/CoreServices.h>
|
||||||
|
|
||||||
|
|
||||||
|
/*< internal >
|
||||||
|
* create_cfstring_from_cstr:
|
||||||
|
* @cstr: a #gchar
|
||||||
|
*
|
||||||
|
* Converts a cstr to a utf8 cfstring
|
||||||
|
* It must be CFReleased()'d.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static CFStringRef
|
||||||
|
create_cfstring_from_cstr (const gchar *cstr)
|
||||||
|
{
|
||||||
|
return CFStringCreateWithCString (NULL, cstr, kCFStringEncodingUTF8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*< internal >
|
||||||
|
* create_cstr_from_cfstring:
|
||||||
|
* @str: a #CFStringRef
|
||||||
|
*
|
||||||
|
* Converts a cfstring to a utf8 cstring.
|
||||||
|
* The incoming cfstring is released for you.
|
||||||
|
* The returned string must be g_free()'d.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static gchar *
|
||||||
|
create_cstr_from_cfstring (CFStringRef str)
|
||||||
|
{
|
||||||
|
const gchar *cstr;
|
||||||
|
|
||||||
|
if (str == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cstr = CFStringGetCStringPtr (str, kCFStringEncodingUTF8);
|
||||||
|
CFRelease (str);
|
||||||
|
|
||||||
|
return g_strdup (cstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*< internal >
|
||||||
|
* create_cstr_from_cfstring_with_fallback:
|
||||||
|
* @str: a #CFStringRef
|
||||||
|
* @fallback: a #gchar
|
||||||
|
*
|
||||||
|
* Tries to convert a cfstring to a utf8 cstring.
|
||||||
|
* If @str is NULL or conversion fails @fallback is returned.
|
||||||
|
* The incoming cfstring is released for you.
|
||||||
|
* The returned string must be g_free()'d.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
static gchar *
|
||||||
|
create_cstr_from_cfstring_with_fallback (CFStringRef str,
|
||||||
|
const gchar *fallback)
|
||||||
|
{
|
||||||
|
gchar *cstr;
|
||||||
|
|
||||||
|
cstr = create_cstr_from_cfstring (str);
|
||||||
|
if (!cstr)
|
||||||
|
return g_strdup (fallback);
|
||||||
|
|
||||||
|
return cstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
g_content_type_equals (const gchar *type1,
|
||||||
|
const gchar *type2)
|
||||||
|
{
|
||||||
|
CFStringRef str1, str2;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (type1 != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (type2 != NULL, FALSE);
|
||||||
|
|
||||||
|
if (g_ascii_strcasecmp (type1, type2) == 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
str1 = create_cfstring_from_cstr (type1);
|
||||||
|
str2 = create_cfstring_from_cstr (type2);
|
||||||
|
|
||||||
|
ret = UTTypeEqual (str1, str2);
|
||||||
|
|
||||||
|
CFRelease (str1);
|
||||||
|
CFRelease (str2);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
g_content_type_is_a (const gchar *ctype,
|
||||||
|
const gchar *csupertype)
|
||||||
|
{
|
||||||
|
CFStringRef type, supertype;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_return_val_if_fail (ctype != NULL, FALSE);
|
||||||
|
g_return_val_if_fail (csupertype != NULL, FALSE);
|
||||||
|
|
||||||
|
type = create_cfstring_from_cstr (ctype);
|
||||||
|
supertype = create_cfstring_from_cstr (csupertype);
|
||||||
|
|
||||||
|
ret = UTTypeConformsTo (type, supertype);
|
||||||
|
|
||||||
|
CFRelease (type);
|
||||||
|
CFRelease (supertype);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
g_content_type_is_unknown (const gchar *type)
|
||||||
|
{
|
||||||
|
g_return_val_if_fail (type != NULL, FALSE);
|
||||||
|
|
||||||
|
/* Should dynamic types be considered "unknown"? */
|
||||||
|
if (g_str_has_prefix (type, "dyn."))
|
||||||
|
return TRUE;
|
||||||
|
/* application/octet-stream */
|
||||||
|
else if (g_strcmp0 (type, "public.data") == 0)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
g_content_type_get_description (const gchar *type)
|
||||||
|
{
|
||||||
|
CFStringRef str;
|
||||||
|
CFStringRef desc_str;
|
||||||
|
|
||||||
|
g_return_val_if_fail (type != NULL, NULL);
|
||||||
|
|
||||||
|
str = create_cfstring_from_cstr (type);
|
||||||
|
desc_str = UTTypeCopyDescription (str);
|
||||||
|
|
||||||
|
CFRelease (str);
|
||||||
|
return create_cstr_from_cfstring_with_fallback (desc_str, "unknown");
|
||||||
|
}
|
||||||
|
|
||||||
|
static GIcon *
|
||||||
|
g_content_type_get_icon_internal (const gchar *type,
|
||||||
|
gboolean symbolic)
|
||||||
|
{
|
||||||
|
GIcon *icon = NULL;
|
||||||
|
gchar *name;
|
||||||
|
|
||||||
|
g_return_val_if_fail (type != NULL, NULL);
|
||||||
|
|
||||||
|
/* TODO: Show mimetype icons. */
|
||||||
|
if (g_content_type_can_be_executable (type))
|
||||||
|
name = "gtk-execute";
|
||||||
|
else if (g_content_type_is_a (type, "public.directory"))
|
||||||
|
name = symbolic ? "inode-directory-symbolic" : "inode-directory";
|
||||||
|
else
|
||||||
|
name = "gtk-file";
|
||||||
|
|
||||||
|
icon = g_themed_icon_new_with_default_fallbacks (name);
|
||||||
|
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
GIcon *
|
||||||
|
g_content_type_get_icon (const gchar *type)
|
||||||
|
{
|
||||||
|
return g_content_type_get_icon_internal (type, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
GIcon *
|
||||||
|
g_content_type_get_symbolic_icon (const gchar *type)
|
||||||
|
{
|
||||||
|
return g_content_type_get_icon_internal (type, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
g_content_type_get_generic_icon_name (const gchar *type)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
g_content_type_can_be_executable (const gchar *type)
|
||||||
|
{
|
||||||
|
CFStringRef uti;
|
||||||
|
gboolean ret = FALSE;
|
||||||
|
|
||||||
|
g_return_val_if_fail (type != NULL, FALSE);
|
||||||
|
|
||||||
|
uti = create_cfstring_from_cstr (type);
|
||||||
|
|
||||||
|
if (UTTypeConformsTo (uti, kUTTypeApplication))
|
||||||
|
ret = TRUE;
|
||||||
|
else if (UTTypeConformsTo (uti, CFSTR("public.executable")))
|
||||||
|
ret = TRUE;
|
||||||
|
else if (UTTypeConformsTo (uti, CFSTR("public.script")))
|
||||||
|
ret = TRUE;
|
||||||
|
|
||||||
|
CFRelease (uti);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
g_content_type_from_mime_type (const gchar *mime_type)
|
||||||
|
{
|
||||||
|
CFStringRef mime_str;
|
||||||
|
CFStringRef uti_str;
|
||||||
|
|
||||||
|
g_return_val_if_fail (mime_type != NULL, NULL);
|
||||||
|
|
||||||
|
/* Their api does not handle globs but they are common. */
|
||||||
|
if (g_str_has_suffix (mime_type, "*"))
|
||||||
|
{
|
||||||
|
if (g_str_has_prefix (mime_type, "audio"))
|
||||||
|
return g_strdup ("public.audio");
|
||||||
|
if (g_str_has_prefix (mime_type, "image"))
|
||||||
|
return g_strdup ("public.image");
|
||||||
|
if (g_str_has_prefix (mime_type, "text"))
|
||||||
|
return g_strdup ("public.text");
|
||||||
|
if (g_str_has_prefix (mime_type, "video"))
|
||||||
|
return g_strdup ("public.movie");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some exceptions are needed for gdk-pixbuf.
|
||||||
|
* This list is not exhaustive.
|
||||||
|
*/
|
||||||
|
if (g_str_has_prefix (mime_type, "image"))
|
||||||
|
{
|
||||||
|
if (g_str_has_suffix (mime_type, "x-icns"))
|
||||||
|
return g_strdup ("com.apple.icns");
|
||||||
|
if (g_str_has_suffix (mime_type, "x-tga"))
|
||||||
|
return g_strdup ("com.truevision.tga-image");
|
||||||
|
if (g_str_has_suffix (mime_type, "x-ico"))
|
||||||
|
return g_strdup ("com.microsoft.ico ");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* These are also not supported...
|
||||||
|
* Used in glocalfileinfo.c
|
||||||
|
*/
|
||||||
|
if (g_str_has_prefix (mime_type, "inode"))
|
||||||
|
{
|
||||||
|
if (g_str_has_suffix (mime_type, "directory"))
|
||||||
|
return g_strdup ("public.directory");
|
||||||
|
if (g_str_has_suffix (mime_type, "symlink"))
|
||||||
|
return g_strdup ("public.symlink");
|
||||||
|
}
|
||||||
|
|
||||||
|
mime_str = create_cfstring_from_cstr (mime_type);
|
||||||
|
uti_str = UTTypeCreatePreferredIdentifierForTag (kUTTagClassMIMEType, mime_str, NULL);
|
||||||
|
|
||||||
|
CFRelease (mime_str);
|
||||||
|
return create_cstr_from_cfstring_with_fallback (uti_str, "public.data");
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
g_content_type_get_mime_type (const gchar *type)
|
||||||
|
{
|
||||||
|
CFStringRef uti_str;
|
||||||
|
CFStringRef mime_str;
|
||||||
|
|
||||||
|
g_return_val_if_fail (type != NULL, NULL);
|
||||||
|
|
||||||
|
/* We must match the additions above
|
||||||
|
* so conversions back and forth work.
|
||||||
|
*/
|
||||||
|
if (g_str_has_prefix (type, "public"))
|
||||||
|
{
|
||||||
|
if (g_str_has_suffix (type, ".image"))
|
||||||
|
return g_strdup ("image/*");
|
||||||
|
if (g_str_has_suffix (type, ".movie"))
|
||||||
|
return g_strdup ("video/*");
|
||||||
|
if (g_str_has_suffix (type, ".text"))
|
||||||
|
return g_strdup ("text/*");
|
||||||
|
if (g_str_has_suffix (type, ".audio"))
|
||||||
|
return g_strdup ("audio/*");
|
||||||
|
if (g_str_has_suffix (type, ".directory"))
|
||||||
|
return g_strdup ("inode/directory");
|
||||||
|
if (g_str_has_suffix (type, ".symlink"))
|
||||||
|
return g_strdup ("inode/symlink");
|
||||||
|
}
|
||||||
|
|
||||||
|
uti_str = create_cfstring_from_cstr (type);
|
||||||
|
mime_str = UTTypeCopyPreferredTagWithClass(uti_str, kUTTagClassMIMEType);
|
||||||
|
|
||||||
|
CFRelease (uti_str);
|
||||||
|
return create_cstr_from_cfstring_with_fallback (mime_str, "application/octet-stream");
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
looks_like_text (const guchar *data,
|
||||||
|
gsize data_size)
|
||||||
|
{
|
||||||
|
gsize i;
|
||||||
|
guchar c;
|
||||||
|
|
||||||
|
for (i = 0; i < data_size; i++)
|
||||||
|
{
|
||||||
|
c = data[i];
|
||||||
|
if (g_ascii_iscntrl (c) && !g_ascii_isspace (c) && c != '\b')
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar *
|
||||||
|
g_content_type_guess (const gchar *filename,
|
||||||
|
const guchar *data,
|
||||||
|
gsize data_size,
|
||||||
|
gboolean *result_uncertain)
|
||||||
|
{
|
||||||
|
CFStringRef uti = NULL;
|
||||||
|
gchar *cextension;
|
||||||
|
CFStringRef extension;
|
||||||
|
|
||||||
|
g_return_val_if_fail (data_size != (gsize) -1, NULL);
|
||||||
|
|
||||||
|
if (filename && *filename)
|
||||||
|
{
|
||||||
|
gchar *basename = g_path_get_basename (filename);
|
||||||
|
gchar *dirname = g_path_get_dirname (filename);
|
||||||
|
gsize i = strlen (filename);
|
||||||
|
|
||||||
|
if (filename[i - 1] == '/')
|
||||||
|
{
|
||||||
|
if (g_strcmp0 (dirname, "/Volumes") == 0)
|
||||||
|
{
|
||||||
|
uti = CFStringCreateCopy (NULL, kUTTypeVolume);
|
||||||
|
}
|
||||||
|
else if ((cextension = strrchr (basename, '.')) != NULL)
|
||||||
|
{
|
||||||
|
cextension++;
|
||||||
|
extension = create_cfstring_from_cstr (cextension);
|
||||||
|
uti = UTTypeCreatePreferredIdentifierForTag (kUTTagClassFilenameExtension,
|
||||||
|
extension, NULL);
|
||||||
|
CFRelease (extension);
|
||||||
|
|
||||||
|
if (CFStringHasPrefix (uti, CFSTR ("dyn.")))
|
||||||
|
{
|
||||||
|
CFRelease (uti);
|
||||||
|
uti = CFStringCreateCopy (NULL, kUTTypeFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uti = CFStringCreateCopy (NULL, kUTTypeFolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* GTK needs this... */
|
||||||
|
if (g_str_has_suffix (basename, ".ui"))
|
||||||
|
{
|
||||||
|
uti = CFStringCreateCopy (NULL, kUTTypeXML);
|
||||||
|
}
|
||||||
|
else if ((cextension = strrchr (basename, '.')) != NULL)
|
||||||
|
{
|
||||||
|
cextension++;
|
||||||
|
extension = create_cfstring_from_cstr (cextension);
|
||||||
|
uti = UTTypeCreatePreferredIdentifierForTag (kUTTagClassFilenameExtension,
|
||||||
|
extension, NULL);
|
||||||
|
CFRelease (extension);
|
||||||
|
}
|
||||||
|
g_free (basename);
|
||||||
|
g_free (dirname);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (data)
|
||||||
|
{
|
||||||
|
if (looks_like_text (data, data_size))
|
||||||
|
{
|
||||||
|
if (g_str_has_prefix ((const gchar*)data, "#!/"))
|
||||||
|
uti = CFStringCreateCopy (NULL, CFSTR ("public.script"));
|
||||||
|
else
|
||||||
|
uti = CFStringCreateCopy (NULL, kUTTypePlainText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!uti)
|
||||||
|
{
|
||||||
|
/* Generic data type */
|
||||||
|
uti = CFStringCreateCopy (NULL, CFSTR ("public.data"));
|
||||||
|
if (result_uncertain)
|
||||||
|
*result_uncertain = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return create_cstr_from_cfstring (uti);
|
||||||
|
}
|
||||||
|
|
||||||
|
GList *
|
||||||
|
g_content_types_get_registered (void)
|
||||||
|
{
|
||||||
|
/* TODO: UTTypeCreateAllIdentifiersForTag? */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
gchar **
|
||||||
|
g_content_type_guess_for_tree (GFile *root)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user